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  }