* Add support for editing/deleting messages * Add support for uploading files * Add support for avatars * Use the Rocket.Chat.Go.SDK * Use the rest and streaming api
5.6 KiB
Gabs is a small utility for dealing with dynamic or unknown JSON
structures in golang. It’s pretty much just a helpful wrapper around the
golang json.Marshal/json.Unmarshal
behaviour and
map[string]interface{}
objects. It does nothing spectacular
except for being fabulous.
https://godoc.org/github.com/Jeffail/gabs
How to install:
go get github.com/Jeffail/gabs
How to use
Parsing and searching JSON
...
import "github.com/Jeffail/gabs"
, err := gabs.ParseJSON([]byte(`{
jsonParsed "outter":{
"inner":{
"value1":10,
"value2":22
},
"alsoInner":{
"value1":20
}
}
}`))
var value float64
var ok bool
, ok = jsonParsed.Path("outter.inner.value1").Data().(float64)
value// value == 10.0, ok == true
, ok = jsonParsed.Search("outter", "inner", "value1").Data().(float64)
value// value == 10.0, ok == true
, ok = jsonParsed.Path("does.not.exist").Data().(float64)
value// value == 0.0, ok == false
:= jsonParsed.Exists("outter", "inner", "value1")
exists // exists == true
:= jsonParsed.Exists("does", "not", "exist")
exists // exists == false
:= jsonParsed.ExistsP("does.not.exist")
exists // exists == false
...
Iterating objects
...
, _ := gabs.ParseJSON([]byte(`{"object":{ "first": 1, "second": 2, "third": 3 }}`))
jsonParsed
// S is shorthand for Search
, _ := jsonParsed.S("object").ChildrenMap()
childrenfor key, child := range children {
.Printf("key: %v, value: %v\n", key, child.Data().(string))
fmt}
...
Iterating arrays
...
, _ := gabs.ParseJSON([]byte(`{"array":[ "first", "second", "third" ]}`))
jsonParsed
// S is shorthand for Search
, _ := jsonParsed.S("array").Children()
childrenfor _, child := range children {
.Println(child.Data().(string))
fmt}
...
Will print:
first
second
third
Children() will return all children of an array in order. This also works on objects, however, the children will be returned in a random order.
Searching through arrays
If your JSON structure contains arrays you can still search the fields of the objects within the array, this returns a JSON array containing the results for each element.
...
, _ := gabs.ParseJSON([]byte(`{"array":[ {"value":1}, {"value":2}, {"value":3} ]}`))
jsonParsed.Println(jsonParsed.Path("array.value").String())
fmt
...
Will print:
[1,2,3]
Generating JSON
...
:= gabs.New()
jsonObj // or gabs.Consume(jsonObject) to work on an existing map[string]interface{}
.Set(10, "outter", "inner", "value")
jsonObj.SetP(20, "outter.inner.value2")
jsonObj.Set(30, "outter", "inner2", "value3")
jsonObj
.Println(jsonObj.String())
fmt
...
Will print:
{"outter":{"inner":{"value":10,"value2":20},"inner2":{"value3":30}}}
To pretty-print:
...
.Println(jsonObj.StringIndent("", " "))
fmt
...
Will print:
{
"outter": {
"inner": {
"value": 10,
"value2": 20
},
"inner2": {
"value3": 30
}
}
}
Generating Arrays
...
:= gabs.New()
jsonObj
.Array("foo", "array")
jsonObj// Or .ArrayP("foo.array")
.ArrayAppend(10, "foo", "array")
jsonObj.ArrayAppend(20, "foo", "array")
jsonObj.ArrayAppend(30, "foo", "array")
jsonObj
.Println(jsonObj.String())
fmt
...
Will print:
{"foo":{"array":[10,20,30]}}
Working with arrays by index:
...
:= gabs.New()
jsonObj
// Create an array with the length of 3
.ArrayOfSize(3, "foo")
jsonObj
.S("foo").SetIndex("test1", 0)
jsonObj.S("foo").SetIndex("test2", 1)
jsonObj
// Create an embedded array with the length of 3
.S("foo").ArrayOfSizeI(3, 2)
jsonObj
.S("foo").Index(2).SetIndex(1, 0)
jsonObj.S("foo").Index(2).SetIndex(2, 1)
jsonObj.S("foo").Index(2).SetIndex(3, 2)
jsonObj
.Println(jsonObj.String())
fmt
...
Will print:
{"foo":["test1","test2",[1,2,3]]}
Converting back to JSON
This is the easiest part:
...
, _ := gabs.ParseJSON([]byte(`{
jsonParsedObj "outter":{
"values":{
"first":10,
"second":11
}
},
"outter2":"hello world"
}`))
:= jsonParsedObj.String()
jsonOutput // Becomes `{"outter":{"values":{"first":10,"second":11}},"outter2":"hello world"}`
...
And to serialize a specific segment is as simple as:
...
:= gabs.ParseJSON([]byte(`{
jsonParsedObj "outter":{
"values":{
"first":10,
"second":11
}
},
"outter2":"hello world"
}`))
:= jsonParsedObj.Search("outter").String()
jsonOutput // Becomes `{"values":{"first":10,"second":11}}`
...
Merge two containers
You can merge a JSON structure into an existing one, where collisions will be converted into a JSON array.
, _ := ParseJSON([]byte(`{"outter": {"value1": "one"}}`))
jsonParsed1, _ := ParseJSON([]byte(`{"outter": {"inner": {"value3": "three"}}, "outter2": {"value2": "two"}}`))
jsonParsed2
.Merge(jsonParsed2)
jsonParsed1// Becomes `{"outter":{"inner":{"value3":"three"},"value1":"one"},"outter2":{"value2":"two"}}`
Arrays are merged:
, _ := ParseJSON([]byte(`{"array": ["one"]}`))
jsonParsed1, _ := ParseJSON([]byte(`{"array": ["two"]}`))
jsonParsed2
.Merge(jsonParsed2)
jsonParsed1// Becomes `{"array":["one", "two"]}`
Parsing Numbers
Gabs uses the json
package under the bonnet, which by
default will parse all number values into float64
. If you
need to parse Int
values then you should use a
json.Decoder
(https://golang.org/pkg/encoding/json/#Decoder):
:= []byte(`{"test":{"int":10, "float":6.66}}`)
sample := json.NewDecoder(bytes.NewReader(sample))
dec .UseNumber()
dec
, err := gabs.ParseJSONDecoder(dec)
valif err != nil {
.Errorf("Failed to parse: %v", err)
treturn
}
, err := val.Path("test.int").Data().(json.Number).Int64() intValue