wfc-server/filter/treenode.go
2026-04-06 07:06:18 -04:00

129 lines
2.8 KiB
Go

// Modified from github.com/zdebeer99/goexpression
package filter
import (
"fmt"
"strings"
)
type TreeNode struct {
Value Token
parent *TreeNode
items []*TreeNode
}
// NewTreeElement Creates a new TreeElement.
func NewTreeNode(value Token) *TreeNode {
return &TreeNode{value, nil, make([]*TreeNode, 0)}
}
// Parent Returns the current element parent
func (n *TreeNode) Parent() *TreeNode {
return n.parent
}
func (n *TreeNode) Root() *TreeNode {
p := n
for p.parent != nil {
p = p.parent
}
return p
}
// setParent sets the current nodes parent value.
// Warning: does not add the node as a child
func (n *TreeNode) setParent(element *TreeNode) {
if n.parent != nil {
panic("TreeNode already attached to a parent node")
}
n.parent = element
}
func (n *TreeNode) LastElement() *TreeNode {
if len(n.items) == 0 {
return nil
}
return n.items[len(n.items)-1]
}
func (n *TreeNode) Last() Token {
last := n.LastElement()
if last != nil {
return last.Value
}
return nil
}
func (n *TreeNode) Items() []*TreeNode {
return n.items
}
// Add adds a TreeElement to the end of the children items of the current node.
func (n *TreeNode) AddElement(element *TreeNode) *TreeNode {
element.setParent(n)
n.items = append(n.items, element)
return element
}
// Add adds a value to the end of the children items of the current node.
func (n *TreeNode) Add(value Token) *TreeNode {
element := NewTreeNode(value)
return n.AddElement(element)
}
// Push, removes the current element from its current parent, place the new value
// in its place and add the current element to the new element. there by pushing the current
// element down the hierachy.
// Example:
// tree: A(B)
// B.Push(C)
// tree: A(C(B))
func (n *TreeNode) PushElement(element *TreeNode) *TreeNode {
parent := n.Parent()
if parent != nil {
//replace the current node with the new node
index := parent.indexOf(n)
parent.items[index] = element
element.setParent(parent)
n.parent = nil
}
//add the current node to the new node
element.AddElement(n)
return element
}
func (n *TreeNode) Push(value Token) *TreeNode {
return n.PushElement(NewTreeNode(value))
}
// FindChildElement Finds a child element in the current nodes children
func (n *TreeNode) indexOf(element *TreeNode) int {
for i, v := range n.items {
if v == element {
return i
}
}
return -1
}
func (n *TreeNode) StringContent() string {
lines := make([]string, len(n.items))
for i, v := range n.items {
lines[i] = v.String()
}
if n.Value.Error() != nil {
return fmt.Sprintf("[ERROR: %s]", n.Value.Error())
} else if len(lines) > 0 {
return strings.Join(lines, ",")
} else {
return ""
}
}
func (n *TreeNode) String() string {
if n.StringContent() == "" {
return n.Value.String()
}
return fmt.Sprintf("[%s:%s]", n.Value.String(), n.StringContent())
}