github.com/apex/up@v1.7.1/internal/logs/parser/ast/ast.go (about) 1 // Package ast provides the log query language abstract syntax tree. 2 package ast 3 4 import ( 5 "fmt" 6 "strconv" 7 "strings" 8 ) 9 10 // Op type. 11 type Op string 12 13 // Op types. 14 const ( 15 LNOT Op = "not" 16 NOT = "!" 17 IN = "in" 18 OR = "||" 19 AND = "&&" 20 NE = "!=" 21 EQ = "=" 22 GT = ">" 23 LT = "<" 24 GE = ">=" 25 LE = "<=" 26 ) 27 28 // Node interface. 29 type Node interface { 30 String() string 31 } 32 33 // Root node. 34 type Root struct { 35 Node Node 36 } 37 38 // String implementation. 39 func (n Root) String() string { 40 return fmt.Sprintf(`{ %s }`, n.Node) 41 } 42 43 // Expr node. 44 type Expr struct { 45 Node Node 46 } 47 48 // String implementation. 49 func (n Expr) String() string { 50 return fmt.Sprintf(`(%s)`, n.Node) 51 } 52 53 // Literal node. 54 type Literal string 55 56 // String implementation. 57 func (n Literal) String() string { 58 return fmt.Sprintf(`%s`, string(n)) 59 } 60 61 // Tuple node. 62 type Tuple []Node 63 64 // String implementation. 65 func (n Tuple) String() string { 66 return fmt.Sprintf(`%#v`, n) 67 } 68 69 // Contains node. 70 type Contains struct { 71 Node Node 72 } 73 74 // String implementation. 75 func (n Contains) String() string { 76 switch v := n.Node.(type) { 77 case String: 78 return fmt.Sprintf(`"*%s*"`, string(v)) 79 default: 80 return fmt.Sprintf(`%s`, n.Node) 81 } 82 } 83 84 // String node. 85 type String string 86 87 // String implementation. 88 func (n String) String() string { 89 return fmt.Sprintf(`$.message = %q`, string(n)) 90 } 91 92 // Property node. 93 type Property string 94 95 // String implementation. 96 func (n Property) String() string { 97 return fmt.Sprintf(`$.%s`, string(n)) 98 } 99 100 // Field node. 101 type Field string 102 103 // String implementation. 104 func (n Field) String() string { 105 return fmt.Sprintf(`$.fields.%s`, string(n)) 106 } 107 108 // Subscript node. 109 type Subscript struct { 110 Left Node 111 Right Node 112 } 113 114 // String implementation. 115 func (n Subscript) String() string { 116 return fmt.Sprintf(`%s[%s]`, n.Left, n.Right) 117 } 118 119 // Member node. 120 type Member struct { 121 Left Node 122 Right Node 123 } 124 125 // String implementation. 126 func (n Member) String() string { 127 return fmt.Sprintf(`%s.%s`, n.Left, n.Right) 128 } 129 130 // Number node. 131 type Number struct { 132 Value float64 133 Unit string 134 } 135 136 // String implementation. 137 func (n Number) String() string { 138 v := n.Value 139 140 switch n.Unit { 141 case "kb": 142 v *= 1 << 10 143 case "mb": 144 v *= 1 << 20 145 case "gb": 146 v *= 1 << 30 147 case "s": 148 v *= 1000 149 } 150 151 return strconv.FormatFloat(v, 'f', -1, 64) 152 } 153 154 // Binary node. 155 type Binary struct { 156 Op Op 157 Left Node 158 Right Node 159 } 160 161 // String implementation. 162 func (n Binary) String() string { 163 switch n.Op { 164 case IN: 165 var s []string 166 for _, v := range n.Right.(Tuple) { 167 s = append(s, fmt.Sprintf(`%s %s %s`, n.Left, EQ, value(v))) 168 } 169 return fmt.Sprintf(`(%s)`, strings.Join(s, " || ")) 170 case EQ, NE, GT, LT, GE, LE: 171 return fmt.Sprintf(`%s %s %s`, n.Left, n.Op, value(n.Right)) 172 default: 173 return fmt.Sprintf(`%s %s %s`, n.Left, n.Op, n.Right) 174 } 175 } 176 177 // Unary node. 178 type Unary struct { 179 Op Op 180 Right Node 181 } 182 183 // String implementation. 184 func (n Unary) String() string { 185 switch n.Op { 186 case LNOT: 187 return fmt.Sprintf(`!(%s)`, n.Right) 188 default: 189 return fmt.Sprintf(`%s%s`, n.Op, n.Right) 190 } 191 } 192 193 // value from node. 194 func value(n Node) string { 195 switch v := n.(type) { 196 case String: 197 return fmt.Sprintf("%q", string(v)) 198 case Field: 199 return fmt.Sprintf("%q", string(v)) 200 default: 201 return n.String() 202 } 203 }