From 6d97050e566d7f4597992609765ad5bec79cf001 Mon Sep 17 00:00:00 2001 From: Philip Conrad Date: Thu, 18 Aug 2022 12:57:55 -0400 Subject: [PATCH] Add UnmarshalJSON implementations. (#232) This commit adds custom UnmarshalJSON implementations around the SelectionSet type, so that it is now possible to directly deserialize an appropriately-formed JSON object into an AST document struct. Signed-off-by: Philip Conrad Signed-off-by: Philip Conrad --- ast/decode.go | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 ast/decode.go diff --git a/ast/decode.go b/ast/decode.go new file mode 100644 index 00000000..d0092055 --- /dev/null +++ b/ast/decode.go @@ -0,0 +1,216 @@ +package ast + +import ( + "encoding/json" +) + +func UnmarshalSelectionSet(b []byte) (SelectionSet, error) { + var tmp []json.RawMessage + + if err := json.Unmarshal(b, &tmp); err != nil { + return nil, err + } + + var result = make([]Selection, 0) + for _, item := range tmp { + var field Field + if err := json.Unmarshal(item, &field); err == nil { + result = append(result, &field) + continue + } + var fragmentSpread FragmentSpread + if err := json.Unmarshal(item, &fragmentSpread); err == nil { + result = append(result, &fragmentSpread) + continue + } + var inlineFragment InlineFragment + if err := json.Unmarshal(item, &inlineFragment); err == nil { + result = append(result, &inlineFragment) + continue + } + } + + return result, nil +} + +func (f *FragmentDefinition) UnmarshalJSON(b []byte) error { + var tmp map[string]json.RawMessage + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + for k := range tmp { + switch k { + case "Name": + err := json.Unmarshal(tmp[k], &f.Name) + if err != nil { + return err + } + case "VariableDefinition": + err := json.Unmarshal(tmp[k], &f.VariableDefinition) + if err != nil { + return err + } + case "TypeCondition": + err := json.Unmarshal(tmp[k], &f.TypeCondition) + if err != nil { + return err + } + case "Directives": + err := json.Unmarshal(tmp[k], &f.Directives) + if err != nil { + return err + } + case "SelectionSet": + ss, err := UnmarshalSelectionSet(tmp[k]) + if err != nil { + return err + } + f.SelectionSet = ss + case "Definition": + err := json.Unmarshal(tmp[k], &f.Definition) + if err != nil { + return err + } + case "Position": + err := json.Unmarshal(tmp[k], &f.Position) + if err != nil { + return err + } + } + } + return nil +} + +func (f *InlineFragment) UnmarshalJSON(b []byte) error { + var tmp map[string]json.RawMessage + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + for k := range tmp { + switch k { + case "TypeCondition": + err := json.Unmarshal(tmp[k], &f.TypeCondition) + if err != nil { + return err + } + case "Directives": + err := json.Unmarshal(tmp[k], &f.Directives) + if err != nil { + return err + } + case "SelectionSet": + ss, err := UnmarshalSelectionSet(tmp[k]) + if err != nil { + return err + } + f.SelectionSet = ss + case "ObjectDefinition": + err := json.Unmarshal(tmp[k], &f.ObjectDefinition) + if err != nil { + return err + } + case "Position": + err := json.Unmarshal(tmp[k], &f.Position) + if err != nil { + return err + } + } + } + return nil +} + +func (f *OperationDefinition) UnmarshalJSON(b []byte) error { + var tmp map[string]json.RawMessage + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + for k := range tmp { + switch k { + case "Operation": + err := json.Unmarshal(tmp[k], &f.Operation) + if err != nil { + return err + } + case "Name": + err := json.Unmarshal(tmp[k], &f.Name) + if err != nil { + return err + } + case "VariableDefinitions": + err := json.Unmarshal(tmp[k], &f.VariableDefinitions) + if err != nil { + return err + } + case "Directives": + err := json.Unmarshal(tmp[k], &f.Directives) + if err != nil { + return err + } + case "SelectionSet": + ss, err := UnmarshalSelectionSet(tmp[k]) + if err != nil { + return err + } + f.SelectionSet = ss + case "Position": + err := json.Unmarshal(tmp[k], &f.Position) + if err != nil { + return err + } + } + } + return nil +} + +func (f *Field) UnmarshalJSON(b []byte) error { + var tmp map[string]json.RawMessage + if err := json.Unmarshal(b, &tmp); err != nil { + return err + } + for k := range tmp { + switch k { + case "Alias": + err := json.Unmarshal(tmp[k], &f.Alias) + if err != nil { + return err + } + case "Name": + err := json.Unmarshal(tmp[k], &f.Name) + if err != nil { + return err + } + case "Arguments": + err := json.Unmarshal(tmp[k], &f.Arguments) + if err != nil { + return err + } + case "Directives": + err := json.Unmarshal(tmp[k], &f.Directives) + if err != nil { + return err + } + case "SelectionSet": + ss, err := UnmarshalSelectionSet(tmp[k]) + if err != nil { + return err + } + f.SelectionSet = ss + case "Position": + err := json.Unmarshal(tmp[k], &f.Position) + if err != nil { + return err + } + case "Definition": + err := json.Unmarshal(tmp[k], &f.Definition) + if err != nil { + return err + } + case "ObjectDefinition": + err := json.Unmarshal(tmp[k], &f.ObjectDefinition) + if err != nil { + return err + } + } + } + return nil +}