path.gno
1.45 Kb ยท 78 lines
1package json
2
3import (
4 "errors"
5)
6
7// ParsePath takes a JSONPath string and returns a slice of strings representing the path segments.
8func ParsePath(path string) ([]string, error) {
9 buf := newBuffer([]byte(path))
10 result := make([]string, 0)
11
12 for {
13 b, err := buf.current()
14 if err != nil {
15 break
16 }
17
18 switch {
19 case b == dollarSign || b == atSign:
20 result = append(result, string(b))
21 buf.step()
22
23 case b == dot:
24 buf.step()
25
26 if next, _ := buf.current(); next == dot {
27 buf.step()
28 result = append(result, "..")
29
30 extractNextSegment(buf, &result)
31 } else {
32 extractNextSegment(buf, &result)
33 }
34
35 case b == bracketOpen:
36 start := buf.index
37 buf.step()
38
39 for {
40 if buf.index >= buf.length || buf.data[buf.index] == bracketClose {
41 break
42 }
43
44 buf.step()
45 }
46
47 if buf.index >= buf.length {
48 return nil, errors.New("unexpected end of path")
49 }
50
51 segment := string(buf.sliceFromIndices(start+1, buf.index))
52 result = append(result, segment)
53
54 buf.step()
55
56 default:
57 buf.step()
58 }
59 }
60
61 return result, nil
62}
63
64// extractNextSegment extracts the segment from the current index
65// to the next significant character and adds it to the resulting slice.
66func extractNextSegment(buf *buffer, result *[]string) {
67 start := buf.index
68 buf.skipToNextSignificantToken()
69
70 if buf.index <= start {
71 return
72 }
73
74 segment := string(buf.sliceFromIndices(start, buf.index))
75 if segment != "" {
76 *result = append(*result, segment)
77 }
78}