wfc-server/serverbrowser/filter/treenode.go
2023-12-03 07:41:55 -05:00

129 lines
2.9 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 (this *TreeNode) Parent() *TreeNode {
return this.parent
}
func (this *TreeNode) Root() *TreeNode {
p := this
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 (this *TreeNode) setParent(element *TreeNode) {
if this.parent != nil {
panic("TreeNode already attached to a parent node")
}
this.parent = element
}
func (this *TreeNode) LastElement() *TreeNode {
if len(this.items) == 0 {
return nil
}
return this.items[len(this.items)-1]
}
func (this *TreeNode) Last() Token {
last := this.LastElement()
if last != nil {
return last.Value
}
return nil
}
func (this *TreeNode) Items() []*TreeNode {
return this.items
}
// Add adds a TreeElement to the end of the children items of the current node.
func (this *TreeNode) AddElement(element *TreeNode) *TreeNode {
element.setParent(this)
this.items = append(this.items, element)
return element
}
// Add adds a value to the end of the children items of the current node.
func (this *TreeNode) Add(value Token) *TreeNode {
element := NewTreeNode(value)
return this.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 (this *TreeNode) PushElement(element *TreeNode) *TreeNode {
parent := this.Parent()
if parent != nil {
//replace the current node with the new node
index := parent.indexOf(this)
parent.items[index] = element
element.setParent(parent)
this.parent = nil
}
//add the current node to the new node
element.AddElement(this)
return element
}
func (this *TreeNode) Push(value Token) *TreeNode {
return this.PushElement(NewTreeNode(value))
}
// FindChildElement Finds a child element in the current nodes children
func (this *TreeNode) indexOf(element *TreeNode) int {
for i, v := range this.items {
if v == element {
return i
}
}
return -1
}
func (this *TreeNode) StringContent() string {
lines := make([]string, len(this.items))
for i, v := range this.items {
lines[i] = v.String()
}
if this.Value.Error() != nil {
return fmt.Sprintf("[ERROR: %s]", this.Value.Error())
} else if len(lines) > 0 {
return fmt.Sprintf("%s", strings.Join(lines, ","))
} else {
return ""
}
}
func (this *TreeNode) String() string {
if this.StringContent() == "" {
return this.Value.String()
}
return fmt.Sprintf("[%s:%s]", this.Value.String(), this.StringContent())
}