github.com/mithrandie/csvq@v1.18.1/lib/json/query_structure.go (about) 1 package json 2 3 import ( 4 "strconv" 5 ) 6 7 type QueryExpression interface{} 8 9 type Element struct { 10 Label string 11 Child QueryExpression 12 } 13 14 func (e Element) FieldLabel() string { 15 label := EscapeIdentifier(e.Label) 16 17 if e.Child != nil { 18 switch e.Child.(type) { 19 case Element: 20 label = label + string(PathSeparator) + e.Child.(Element).FieldLabel() 21 case ArrayItem: 22 label = label + e.Child.(ArrayItem).FieldLabel() 23 } 24 } 25 return label 26 } 27 28 type ArrayItem struct { 29 Index int 30 Child QueryExpression 31 } 32 33 func (e ArrayItem) FieldLabel() string { 34 label := "[" + strconv.Itoa(e.Index) + "]" 35 if e.Child != nil { 36 switch e.Child.(type) { 37 case Element: 38 label = label + string(PathSeparator) + e.Child.(Element).FieldLabel() 39 case ArrayItem: 40 label = label + e.Child.(ArrayItem).FieldLabel() 41 } 42 } 43 return label 44 } 45 46 type RowValueExpr struct { 47 Child QueryExpression 48 } 49 50 type TableExpr struct { 51 Fields []FieldExpr 52 } 53 54 type FieldExpr struct { 55 Element Element 56 Alias string 57 } 58 59 func (e FieldExpr) FieldLabel() string { 60 var label string 61 62 if 0 < len(e.Alias) { 63 label = e.Alias 64 } else { 65 label = e.Element.FieldLabel() 66 } 67 68 return label 69 } 70 71 func EscapeIdentifier(s string) string { 72 escaped := make([]rune, 0, len(s)+10) 73 runes := []rune(s) 74 75 for _, r := range runes { 76 switch r { 77 case PathSeparator, PathEscape: 78 escaped = append(escaped, PathEscape, r) 79 default: 80 escaped = append(escaped, r) 81 } 82 } 83 84 return string(escaped) 85 }