aboutsummaryrefslogtreecommitdiff
path: root/model
diff options
context:
space:
mode:
authorNeonXP <i@neonxp.dev>2022-11-16 21:35:48 +0300
committerNeonXP <i@neonxp.dev>2022-11-16 21:35:48 +0300
commiteb26d597c6d526f84077afdc141b0a5d585c7da3 (patch)
treea07e5e4c79e3217afb87877287315bb8590b989f /model
parentc730afe0f889587630789c4fa38267d1edf465f2 (diff)
Utility methodsv0.0.1
Diffstat (limited to 'model')
-rw-r--r--model/array.go10
-rw-r--r--model/condition.go55
-rw-r--r--model/map.go9
-rw-r--r--model/node.go30
4 files changed, 104 insertions, 0 deletions
diff --git a/model/array.go b/model/array.go
index b3d2586..5d64209 100644
--- a/model/array.go
+++ b/model/array.go
@@ -30,3 +30,13 @@ func (n *Node) Each(cb func(idx int, value *Node) error) error {
}
return nil
}
+
+// RemoveIndex from array
+func (n *Node) RemoveIndex(idx int) error {
+ arrlen := len(n.arrayValue)
+ if idx >= arrlen {
+ return fmt.Errorf("index %d out of range (len=%d)", idx, arrlen)
+ }
+ n.arrayValue = append(n.arrayValue[:idx], n.arrayValue[idx:]...)
+ return nil
+}
diff --git a/model/condition.go b/model/condition.go
new file mode 100644
index 0000000..0b558b4
--- /dev/null
+++ b/model/condition.go
@@ -0,0 +1,55 @@
+package model
+
+// Compare current node with another node
+func (n *Node) Compare(op Operand, node *Node) bool {
+ switch op {
+ case OpEq:
+ return n.Value() == node.Value()
+ case OpNeq:
+ return n.Value() != node.Value()
+ case OpLess:
+ return less(n, node)
+ case OpGt:
+ return less(node, n)
+ case OpLessEq:
+ return less(n, node) || n.Value() == node.Value()
+ case OpGtEq:
+ return less(node, n) || n.Value() == node.Value()
+ case OpIn:
+ if n.Type != ArrayNode {
+ return false
+ }
+ for _, v := range n.arrayValue {
+ if v.Value() == node.Value() {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func less(n1 *Node, n2 *Node) bool {
+ if n1.Type != n2.Type {
+ return false
+ }
+ switch n1.Type {
+ case NumberNode:
+ return n1.numberValue < n2.numberValue
+ case StringNode:
+ return n1.stringValue < n2.stringValue
+ default:
+ return false
+ }
+}
+
+type Operand int
+
+const (
+ OpEq Operand = iota
+ OpNeq
+ OpLess
+ OpLessEq
+ OpGt
+ OpGtEq
+ OpIn
+)
diff --git a/model/map.go b/model/map.go
index 59ba2d8..7bfdaa3 100644
--- a/model/map.go
+++ b/model/map.go
@@ -41,3 +41,12 @@ func (n *Node) Map(cb func(key string, value *Node) (*Node, error)) error {
}
return nil
}
+
+// Remove by key from object
+func (n *Node) Remove(key string) error {
+ if n.Type != ObjectNode {
+ return fmt.Errorf("node must be object, got %s", n.Type)
+ }
+ delete(n.objectValue, key)
+ return nil
+}
diff --git a/model/node.go b/model/node.go
index 1483eaf..fea8fcd 100644
--- a/model/node.go
+++ b/model/node.go
@@ -113,3 +113,33 @@ func (n *Node) MarshalJSON() ([]byte, error) {
return []byte("null"), nil
}
}
+
+// Merge two object or array nodes
+func (n *Node) Merge(node *Node) error {
+ if n.Type != node.Type {
+ return fmt.Errorf("can't merge nodes of different types")
+ }
+ switch n.Type {
+ case ObjectNode:
+ for k, v := range node.objectValue {
+ n.objectValue[k] = v
+ }
+ case ArrayNode:
+ n.arrayValue = append(n.arrayValue, node.arrayValue...)
+ default:
+ return fmt.Errorf("merge not implemented for type %s", n.Type)
+ }
+ return nil
+}
+
+// Len returns length of object or array nodes
+func (n *Node) Len() (int, error) {
+ switch n.Type {
+ case ObjectNode:
+ return len(n.objectValue), nil
+ case ArrayNode:
+ return len(n.arrayValue), nil
+ default:
+ return 0, fmt.Errorf("merge not implemented for type %s", n.Type)
+ }
+}