...
1 package graphql
2
3 import (
4 "context"
5
6 "github.com/vektah/gqlparser/v2/ast"
7 )
8
9 const fieldInputCtx key = "path_context"
10
11 type PathContext struct {
12 ParentField *FieldContext
13 Parent *PathContext
14 Field *string
15 Index *int
16 }
17
18 func (fic *PathContext) Path() ast.Path {
19 var path ast.Path
20 for it := fic; it != nil; it = it.Parent {
21 if it.Index != nil {
22 path = append(path, ast.PathIndex(*it.Index))
23 } else if it.Field != nil {
24 path = append(path, ast.PathName(*it.Field))
25 }
26 }
27
28
29 for i := len(path)/2 - 1; i >= 0; i-- {
30 opp := len(path) - 1 - i
31 path[i], path[opp] = path[opp], path[i]
32 }
33
34 if fic.ParentField != nil {
35 fieldPath := fic.ParentField.Path()
36 return append(fieldPath, path...)
37
38 }
39
40 return path
41 }
42
43 func NewPathWithField(field string) *PathContext {
44 return &PathContext{Field: &field}
45 }
46
47 func NewPathWithIndex(index int) *PathContext {
48 return &PathContext{Index: &index}
49 }
50
51 func WithPathContext(ctx context.Context, fic *PathContext) context.Context {
52 if fieldContext := GetFieldContext(ctx); fieldContext != nil {
53 fic.ParentField = fieldContext
54 }
55 if fieldInputContext := GetPathContext(ctx); fieldInputContext != nil {
56 fic.Parent = fieldInputContext
57 }
58
59 return context.WithValue(ctx, fieldInputCtx, fic)
60 }
61
62 func GetPathContext(ctx context.Context) *PathContext {
63 if val, ok := ctx.Value(fieldInputCtx).(*PathContext); ok {
64 return val
65 }
66 return nil
67 }
68
69 func GetPath(ctx context.Context) ast.Path {
70 if pc := GetPathContext(ctx); pc != nil {
71 return pc.Path()
72 }
73 if fc := GetFieldContext(ctx); fc != nil {
74 return fc.Path()
75 }
76 return nil
77 }
78
View as plain text