-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathstraf.go
118 lines (94 loc) · 2.81 KB
/
straf.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package straf
import (
"errors"
"reflect"
"github.com/graphql-go/graphql"
)
// GetGraphQLObject Converts struct into graphql object
func GetGraphQLObject(object interface{}) (*graphql.Object, error) {
objectType := reflect.TypeOf(object)
fields := convertStruct(objectType)
output := graphql.NewObject(
graphql.ObjectConfig{
Name: objectType.Name(),
Fields: fields,
},
)
return output, nil
}
// convertStructToObject converts simple struct to graphql object
func convertStructToObject(
objectType reflect.Type) *graphql.Object {
fields := convertStruct(objectType)
return graphql.NewObject(
graphql.ObjectConfig{
Name: objectType.Name(),
Fields: fields,
},
)
}
// convertStruct converts struct to graphql fields
func convertStruct(objectType reflect.Type) graphql.Fields {
fields := graphql.Fields{}
for i := 0; i < objectType.NumField(); i++ {
currentField := objectType.Field(i)
fieldType := getFieldType(currentField)
if getTagValue(currentField, "exclude") != "true" {
fields[currentField.Name] = &graphql.Field{
Name: currentField.Name,
Type: fieldType,
DeprecationReason: getTagValue(currentField, "deprecationReason"),
Description: getTagValue(currentField, "description"),
}
}
}
return fields
}
// getFieldType Converts object to a graphQL field type
func getFieldType(object reflect.StructField) graphql.Output {
isID, ok := object.Tag.Lookup("unique")
if isID == "true" && ok {
return graphql.ID
}
objectType := object.Type
if objectType.Kind() == reflect.Struct {
return convertStructToObject(objectType)
} else if objectType.Kind() == reflect.Slice &&
objectType.Elem().Kind() == reflect.Struct {
elemType := convertStructToObject(objectType.Elem())
return graphql.NewList(elemType)
} else if objectType.Kind() == reflect.Slice {
elemType, _ := convertSimpleType(objectType.Elem())
return graphql.NewList(elemType)
}
output, _ := convertSimpleType(objectType)
return output
}
// convertSimpleType converts simple type to graphql field
func convertSimpleType(objectType reflect.Type) (*graphql.Scalar, error) {
typeMap := map[reflect.Kind]*graphql.Scalar{
reflect.String: graphql.String,
reflect.Bool: graphql.Boolean,
reflect.Int: graphql.Int,
reflect.Int8: graphql.Int,
reflect.Int16: graphql.Int,
reflect.Int32: graphql.Int,
reflect.Int64: graphql.Int,
reflect.Float32: graphql.Float,
reflect.Float64: graphql.Float,
}
graphqlType, ok := typeMap[objectType.Kind()]
if !ok {
return &graphql.Scalar{}, errors.New("Invalid Type")
}
return graphqlType, nil
}
// getTagValue returns tag value of a struct
func getTagValue(objectType reflect.StructField, tagName string) string {
tag := objectType.Tag
value, ok := tag.Lookup(tagName)
if !ok {
return ""
}
return value
}