...
1
16
17 package field
18
19 import (
20 "bytes"
21 "fmt"
22 "strconv"
23 )
24
25 type pathOptions struct {
26 path *Path
27 }
28
29
30 type PathOption func(o *pathOptions)
31
32
33 func WithPath(p *Path) PathOption {
34 return func(o *pathOptions) {
35 o.path = p
36 }
37 }
38
39
40 func ToPath(opts ...PathOption) *Path {
41 c := &pathOptions{}
42 for _, opt := range opts {
43 opt(c)
44 }
45 return c.path
46 }
47
48
49 type Path struct {
50 name string
51 index string
52 parent *Path
53 }
54
55
56 func NewPath(name string, moreNames ...string) *Path {
57 r := &Path{name: name, parent: nil}
58 for _, anotherName := range moreNames {
59 r = &Path{name: anotherName, parent: r}
60 }
61 return r
62 }
63
64
65 func (p *Path) Root() *Path {
66 for ; p.parent != nil; p = p.parent {
67
68 }
69 return p
70 }
71
72
73 func (p *Path) Child(name string, moreNames ...string) *Path {
74 r := NewPath(name, moreNames...)
75 r.Root().parent = p
76 return r
77 }
78
79
80
81 func (p *Path) Index(index int) *Path {
82 return &Path{index: strconv.Itoa(index), parent: p}
83 }
84
85
86
87 func (p *Path) Key(key string) *Path {
88 return &Path{index: key, parent: p}
89 }
90
91
92 func (p *Path) String() string {
93 if p == nil {
94 return "<nil>"
95 }
96
97 elems := []*Path{}
98 for ; p != nil; p = p.parent {
99 elems = append(elems, p)
100 }
101
102
103 buf := bytes.NewBuffer(nil)
104 for i := range elems {
105 p := elems[len(elems)-1-i]
106 if p.parent != nil && len(p.name) > 0 {
107
108 buf.WriteString(".")
109 }
110 if len(p.name) > 0 {
111 buf.WriteString(p.name)
112 } else {
113 fmt.Fprintf(buf, "[%s]", p.index)
114 }
115 }
116 return buf.String()
117 }
118
View as plain text