Files
opencloud/pkg/kql/factory.go
Jörn Friedrich Dreyer b07b5a1149 use plain pkg module
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2025-01-13 16:42:19 +01:00

210 lines
3.5 KiB
Go

package kql
import (
"strings"
"github.com/opencloud-eu/opencloud/pkg/ast"
)
func base(text []byte, pos position) (*ast.Base, error) {
source, err := toString(text)
if err != nil {
return nil, err
}
return &ast.Base{
Loc: &ast.Location{
Start: ast.Position{
Line: pos.line,
Column: pos.col,
},
End: ast.Position{
Line: pos.line,
Column: pos.col + len(text),
},
Source: &source,
},
}, nil
}
func buildAST(n interface{}, text []byte, pos position) (*ast.Ast, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
nodes, err := toNodes[ast.Node](n)
if err != nil {
return nil, err
}
a := &ast.Ast{
Base: b,
Nodes: connectNodes(DefaultConnector{sameKeyOPValue: BoolOR}, nodes...),
}
if err := validateAst(a); err != nil {
return nil, err
}
return a, nil
}
func buildStringNode(k, v interface{}, text []byte, pos position) (*ast.StringNode, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
key, err := toString(k)
if err != nil {
return nil, err
}
value, err := toString(v)
if err != nil {
return nil, err
}
return &ast.StringNode{
Base: b,
Key: key,
Value: value,
}, nil
}
func buildDateTimeNode(k, o, v interface{}, text []byte, pos position) (*ast.DateTimeNode, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
operator, err := toNode[*ast.OperatorNode](o)
if err != nil {
return nil, err
}
key, err := toString(k)
if err != nil {
return nil, err
}
value, err := toTime(v)
if err != nil {
return nil, err
}
return &ast.DateTimeNode{
Base: b,
Key: key,
Operator: operator,
Value: value,
}, nil
}
func buildNaturalLanguageDateTimeNodes(k, v interface{}, text []byte, pos position) ([]ast.Node, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
key, err := toString(k)
if err != nil {
return nil, err
}
from, to, err := toTimeRange(v)
if err != nil {
return nil, err
}
return []ast.Node{
&ast.DateTimeNode{
Base: b,
Value: *from,
Key: key,
Operator: &ast.OperatorNode{Value: ">="},
},
&ast.OperatorNode{Value: BoolAND},
&ast.DateTimeNode{
Base: b,
Value: *to,
Key: key,
Operator: &ast.OperatorNode{Value: "<="},
},
}, nil
}
func buildBooleanNode(k, v interface{}, text []byte, pos position) (*ast.BooleanNode, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
key, err := toString(k)
if err != nil {
return nil, err
}
value, err := toString(v)
if err != nil {
return nil, err
}
return &ast.BooleanNode{
Base: b,
Key: key,
Value: strings.ToLower(value) == "true",
}, nil
}
func buildOperatorNode(text []byte, pos position) (*ast.OperatorNode, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
value, err := toString(text)
if err != nil {
return nil, err
}
switch value {
case "+":
value = BoolAND
case "-":
value = BoolNOT
}
return &ast.OperatorNode{
Base: b,
Value: value,
}, nil
}
func buildGroupNode(k, n interface{}, text []byte, pos position) (*ast.GroupNode, error) {
b, err := base(text, pos)
if err != nil {
return nil, err
}
key, _ := toString(k)
nodes, err := toNodes[ast.Node](n)
if err != nil {
return nil, err
}
gn := &ast.GroupNode{
Base: b,
Key: key,
Nodes: connectNodes(DefaultConnector{sameKeyOPValue: BoolOR}, nodes...),
}
if err := validateGroupNode(gn); err != nil {
return nil, err
}
return gn, nil
}