/
types_resolver.go
95 lines (85 loc) · 2.43 KB
/
types_resolver.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
package graphql
import (
"fmt"
"go/types"
)
var buildInTypeMaps = map[string]string{
"time.Time": BuiltInTypeTime,
"map[string]interface{}": BuiltInTypeMap,
"interface{}": BuiltInTypeAny,
}
type typeResolver func(types.Type) (string, Dependency, error)
func namedResolver(t types.Type) (string, Dependency, error) {
named := t.(*types.Named)
if t, ok := buildInTypeMaps[named.String()]; ok {
// return t, nil, nil
return t, &ScalarDependency{scalerType: named}, nil
}
underlying := named.Underlying()
switch underlying.(type) {
case *types.Struct:
return named.Obj().Name(), &StructDependency{
namedRef: named,
structRef: underlying.(*types.Struct),
}, nil
case *types.Basic:
return named.Obj().Name(), &ScalarDependency{scalerType: named}, nil
case *types.Interface:
return named.Obj().Name(), &InterfaceDependency{
namedRef: named,
interfaceRef: underlying.(*types.Interface),
}, nil
}
return "", nil, unsupportedError(t)
}
func basicResolver(t types.Type) (string, Dependency, error) {
basic := t.(*types.Basic)
// https://org/graphql-js/basic-types/
// String, Int, Float, Boolean, and ID
info := basic.Info()
if info&types.IsString == types.IsString {
return BasicTypeString, nil, nil
}
if info&types.IsInteger == types.IsInteger {
return BasicTypeInteger, nil, nil
}
if info&types.IsFloat == types.IsFloat {
if basic.Kind() != types.Float64 {
return "", nil, unsupportedError(basic)
}
return BasicTypeFloat, nil, nil
}
if info&types.IsBoolean == types.IsBoolean {
return BasicTypeBoolean, nil, nil
}
return "", nil, unsupportedError(t)
}
func mapResolver(t types.Type) (string, Dependency, error) {
m := t.(*types.Map)
if _, ok := m.Elem().(*types.Interface); !ok {
return "", nil, unsupportedError(t)
}
return BuiltInTypeMap, &ScalarDependency{scalerType: m}, nil
}
func interfaceResolver(t types.Type) (string, Dependency, error) {
return BuiltInTypeAny, &ScalarDependency{scalerType: t}, nil
}
func resolveResolver(t types.Type) (typeResolver, error) {
switch t.(type) {
case *types.Named:
return namedResolver, nil
case *types.Basic:
return basicResolver, nil
case *types.Map:
return mapResolver, nil
case *types.Interface:
return interfaceResolver, nil
}
return nil, unsupportedError(t)
}
var (
ErrUnsupportedType = fmt.Errorf("unsupported type")
)
func unsupportedError(t types.Type) error {
return fmt.Errorf("%w: %s", ErrUnsupportedType, t)
}