summaryrefslogtreecommitdiff
path: root/json/node.go
diff options
context:
space:
mode:
authorFelix Hanley <felix@userspace.com.au>2018-11-16 06:28:50 +0000
committerFelix Hanley <felix@userspace.com.au>2018-11-16 06:28:50 +0000
commitd6882bd9403c588415c1906a7015d16e92aa1ad3 (patch)
tree86f8c25049454e9d199c8f114f8e9dc52b19c2ba /json/node.go
parentdc0a50a47d1ad749efa298dcdcd732daa33388c9 (diff)
downloadquery-d6882bd9403c588415c1906a7015d16e92aa1ad3.tar.gz
query-d6882bd9403c588415c1906a7015d16e92aa1ad3.tar.bz2
Add node data types and tests
Diffstat (limited to 'json/node.go')
-rw-r--r--json/node.go40
1 files changed, 21 insertions, 19 deletions
diff --git a/json/node.go b/json/node.go
index f219436..eb544dc 100644
--- a/json/node.go
+++ b/json/node.go
@@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"io"
- "io/ioutil"
"sort"
"strconv"
)
@@ -21,13 +20,20 @@ const (
TextNode
)
+var NodeNames = map[NodeType]string{
+ DocumentNode: "DocumentNode",
+ ElementNode: "ElementNode",
+ TextNode: "TextNode",
+}
+
// A Node consists of a NodeType and some Data (tag name for
// element nodes, content for text) and are part of a tree of Nodes.
type Node struct {
Parent, PrevSibling, NextSibling, FirstChild, LastChild *Node
- Type NodeType
- Data string
+ Type NodeType
+ Data string
+ DataType string
level int
}
@@ -91,10 +97,13 @@ func parseValue(x interface{}, top *Node, level int) {
}
}
}
+
+ // TODO check for null
+
switch v := x.(type) {
case []interface{}:
for _, vv := range v {
- n := &Node{Type: ElementNode, level: level}
+ n := &Node{Type: ElementNode, level: level, DataType: "array"}
addNode(n)
parseValue(vv, n, level+1)
}
@@ -107,39 +116,32 @@ func parseValue(x interface{}, top *Node, level int) {
}
sort.Strings(keys)
for _, key := range keys {
- n := &Node{Data: key, Type: ElementNode, level: level}
+ n := &Node{Data: key, Type: ElementNode, level: level, DataType: "object"}
addNode(n)
parseValue(v[key], n, level+1)
}
case string:
- n := &Node{Data: v, Type: TextNode, level: level}
+ n := &Node{Data: v, Type: TextNode, level: level, DataType: "string"}
addNode(n)
case float64:
s := strconv.FormatFloat(v, 'f', -1, 64)
- n := &Node{Data: s, Type: TextNode, level: level}
+ n := &Node{Data: s, Type: TextNode, level: level, DataType: "number"}
addNode(n)
case bool:
s := strconv.FormatBool(v)
- n := &Node{Data: s, Type: TextNode, level: level}
+ n := &Node{Data: s, Type: TextNode, level: level, DataType: "boolean"}
addNode(n)
}
}
-func parse(b []byte) (*Node, error) {
+// Parse JSON document.
+func Parse(r io.Reader) (*Node, error) {
var v interface{}
- if err := json.Unmarshal(b, &v); err != nil {
+ decoder := json.NewDecoder(r)
+ if err := decoder.Decode(&v); err != nil {
return nil, err
}
doc := &Node{Type: DocumentNode}
parseValue(v, doc, 1)
return doc, nil
}
-
-// Parse JSON document.
-func Parse(r io.Reader) (*Node, error) {
- b, err := ioutil.ReadAll(r)
- if err != nil {
- return nil, err
- }
- return parse(b)
-}