github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/json/path.gno (about) 1 package json 2 3 import ( 4 "errors" 5 ) 6 7 // ParsePath takes a JSONPath string and returns a slice of strings representing the path segments. 8 func 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. 66 func 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 }