4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-09-11 08:52:30 +00:00

Update vendor (#1330)

This commit is contained in:
Wim
2020-12-06 23:16:02 +01:00
committed by GitHub
parent 4913766d58
commit 0d7315249d
28 changed files with 586 additions and 339 deletions

View File

@@ -7,21 +7,17 @@ It does nothing spectacular except for being fabulous.
https://godoc.org/github.com/Jeffail/gabs
## How to install:
## Install
``` bash
go get github.com/Jeffail/gabs
```
## How to use
## Use
### Parsing and searching JSON
``` go
...
import "github.com/Jeffail/gabs"
jsonParsed, err := gabs.ParseJSON([]byte(`{
"outter":{
"inner":{
@@ -29,7 +25,10 @@ jsonParsed, err := gabs.ParseJSON([]byte(`{
"value2":22
},
"alsoInner":{
"value1":20
"value1":20,
"array1":[
30, 40
]
}
}
}`))
@@ -43,26 +42,26 @@ value, ok = jsonParsed.Path("outter.inner.value1").Data().(float64)
value, ok = jsonParsed.Search("outter", "inner", "value1").Data().(float64)
// value == 10.0, ok == true
gObj, err := jsonParsed.JSONPointer("/outter/alsoInner/array1/1")
if err != nil {
panic(err)
}
value, ok = gObj.Data().(float64)
// value == 40.0, ok == true
value, ok = jsonParsed.Path("does.not.exist").Data().(float64)
// value == 0.0, ok == false
exists := jsonParsed.Exists("outter", "inner", "value1")
// exists == true
exists := jsonParsed.Exists("does", "not", "exist")
// exists == false
exists := jsonParsed.ExistsP("does.not.exist")
// exists == false
...
```
### Iterating objects
``` go
...
jsonParsed, _ := gabs.ParseJSON([]byte(`{"object":{ "first": 1, "second": 2, "third": 3 }}`))
// S is shorthand for Search
@@ -70,24 +69,25 @@ children, _ := jsonParsed.S("object").ChildrenMap()
for key, child := range children {
fmt.Printf("key: %v, value: %v\n", key, child.Data().(string))
}
...
```
### Iterating arrays
``` go
...
jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":[ "first", "second", "third" ]}`))
jsonParsed, err := gabs.ParseJSON([]byte(`{"array":[ "first", "second", "third" ]}`))
if err != nil {
panic(err)
}
// S is shorthand for Search
children, _ := jsonParsed.S("array").Children()
children, err := jsonParsed.S("array").Children()
if err != nil {
panic(err)
}
for _, child := range children {
fmt.Println(child.Data().(string))
}
...
```
Will print:
@@ -108,12 +108,11 @@ objects within the array, this returns a JSON array containing the results for
each element.
``` go
...
jsonParsed, _ := gabs.ParseJSON([]byte(`{"array":[ {"value":1}, {"value":2}, {"value":3} ]}`))
jsonParsed, err := gabs.ParseJSON([]byte(`{"array":[ {"value":1}, {"value":2}, {"value":3} ]}`))
if err != nil {
panic(err)
}
fmt.Println(jsonParsed.Path("array.value").String())
...
```
Will print:
@@ -125,8 +124,6 @@ Will print:
### Generating JSON
``` go
...
jsonObj := gabs.New()
// or gabs.Consume(jsonObject) to work on an existing map[string]interface{}
@@ -135,8 +132,6 @@ jsonObj.SetP(20, "outter.inner.value2")
jsonObj.Set(30, "outter", "inner2", "value3")
fmt.Println(jsonObj.String())
...
```
Will print:
@@ -148,11 +143,7 @@ Will print:
To pretty-print:
``` go
...
fmt.Println(jsonObj.StringIndent("", " "))
...
```
Will print:
@@ -174,8 +165,6 @@ Will print:
### Generating Arrays
``` go
...
jsonObj := gabs.New()
jsonObj.Array("foo", "array")
@@ -186,8 +175,6 @@ jsonObj.ArrayAppend(20, "foo", "array")
jsonObj.ArrayAppend(30, "foo", "array")
fmt.Println(jsonObj.String())
...
```
Will print:
@@ -199,8 +186,6 @@ Will print:
Working with arrays by index:
``` go
...
jsonObj := gabs.New()
// Create an array with the length of 3
@@ -217,8 +202,6 @@ jsonObj.S("foo").Index(2).SetIndex(2, 1)
jsonObj.S("foo").Index(2).SetIndex(3, 2)
fmt.Println(jsonObj.String())
...
```
Will print:
@@ -232,8 +215,6 @@ Will print:
This is the easiest part:
``` go
...
jsonParsedObj, _ := gabs.ParseJSON([]byte(`{
"outter":{
"values":{
@@ -246,15 +227,11 @@ jsonParsedObj, _ := gabs.ParseJSON([]byte(`{
jsonOutput := jsonParsedObj.String()
// Becomes `{"outter":{"values":{"first":10,"second":11}},"outter2":"hello world"}`
...
```
And to serialize a specific segment is as simple as:
``` go
...
jsonParsedObj := gabs.ParseJSON([]byte(`{
"outter":{
"values":{
@@ -267,8 +244,6 @@ jsonParsedObj := gabs.ParseJSON([]byte(`{
jsonOutput := jsonParsedObj.Search("outter").String()
// Becomes `{"values":{"first":10,"second":11}}`
...
```
### Merge two containers

View File

@@ -20,58 +20,85 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Package gabs implements a simplified wrapper around creating and parsing JSON.
// Package gabs implements a simplified wrapper around creating and parsing
// unknown or dynamic JSON.
package gabs
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"strconv"
"strings"
)
//--------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------
var (
// ErrOutOfBounds - Index out of bounds.
// ErrOutOfBounds indicates an index was out of bounds.
ErrOutOfBounds = errors.New("out of bounds")
// ErrNotObjOrArray - The target is not an object or array type.
// ErrNotObjOrArray is returned when a target is not an object or array type
// but needs to be for the intended operation.
ErrNotObjOrArray = errors.New("not an object or array")
// ErrNotObj - The target is not an object type.
// ErrNotObj is returned when a target is not an object but needs to be for
// the intended operation.
ErrNotObj = errors.New("not an object")
// ErrNotArray - The target is not an array type.
// ErrNotArray is returned when a target is not an array but needs to be for
// the intended operation.
ErrNotArray = errors.New("not an array")
// ErrPathCollision - Creating a path failed because an element collided with an existing value.
// ErrPathCollision is returned when creating a path failed because an
// element collided with an existing value.
ErrPathCollision = errors.New("encountered value collision whilst building path")
// ErrInvalidInputObj - The input value was not a map[string]interface{}.
// ErrInvalidInputObj is returned when the input value was not a
// map[string]interface{}.
ErrInvalidInputObj = errors.New("invalid input object")
// ErrInvalidInputText - The input data could not be parsed.
// ErrInvalidInputText is returned when the input data could not be parsed.
ErrInvalidInputText = errors.New("input text could not be parsed")
// ErrInvalidPath - The filepath was not valid.
// ErrInvalidPath is returned when the filepath was not valid.
ErrInvalidPath = errors.New("invalid file path")
// ErrInvalidBuffer - The input buffer contained an invalid JSON string
// ErrInvalidBuffer is returned when the input buffer contained an invalid
// JSON string.
ErrInvalidBuffer = errors.New("input buffer contained invalid JSON")
)
//--------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Container - an internal structure that holds a reference to the core interface map of the parsed
// json. Use this container to move context.
func resolveJSONPointerHierarchy(path string) ([]string, error) {
if len(path) < 1 {
return nil, errors.New("failed to resolve JSON pointer: path must not be empty")
}
if path[0] != '/' {
return nil, errors.New("failed to resolve JSON pointer: path must begin with '/'")
}
hierarchy := strings.Split(path, "/")[1:]
for i, v := range hierarchy {
v = strings.Replace(v, "~1", "/", -1)
v = strings.Replace(v, "~0", "~", -1)
hierarchy[i] = v
}
return hierarchy, nil
}
//------------------------------------------------------------------------------
// Container references a specific element within a JSON structure.
type Container struct {
object interface{}
}
// Data - Return the contained data as an interface{}.
// Data returns the underlying interface{} of the target element in the JSON
// structure.
func (g *Container) Data() interface{} {
if g == nil {
return nil
@@ -79,17 +106,18 @@ func (g *Container) Data() interface{} {
return g.object
}
//--------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Path - Search for a value using dot notation.
// Path searches the JSON structure following a path in dot notation.
func (g *Container) Path(path string) *Container {
return g.Search(strings.Split(path, ".")...)
}
// Search - Attempt to find and return an object within the JSON structure by specifying the
// hierarchy of field names to locate the target. If the search encounters an array and has not
// reached the end target then it will iterate each object of the array for the target and return
// all of the results in a JSON array.
// Search attempts to find and return an object within the JSON structure by
// following a provided hierarchy of field names to locate the target. If the
// search encounters an array and has not reached the end target then it will
// iterate each object of the array for the target and return all of the results
// in a JSON array.
func (g *Container) Search(hierarchy ...string) *Container {
var object interface{}
@@ -120,22 +148,55 @@ func (g *Container) Search(hierarchy ...string) *Container {
return &Container{object}
}
// S - Shorthand method, does the same thing as Search.
// JSONPointer parses a JSON pointer path (https://tools.ietf.org/html/rfc6901)
// and either returns a *gabs.Container containing the result or an error if the
// referenced item could not be found.
func (g *Container) JSONPointer(path string) (*Container, error) {
hierarchy, err := resolveJSONPointerHierarchy(path)
if err != nil {
return nil, err
}
object := g.Data()
for target := 0; target < len(hierarchy); target++ {
pathSeg := hierarchy[target]
if mmap, ok := object.(map[string]interface{}); ok {
object, ok = mmap[pathSeg]
if !ok {
return nil, fmt.Errorf("failed to resolve JSON pointer: index '%v' value '%v' was not found", target, pathSeg)
}
} else if marray, ok := object.([]interface{}); ok {
index, err := strconv.Atoi(pathSeg)
if err != nil {
return nil, fmt.Errorf("failed to resolve JSON pointer: could not parse index '%v' value '%v' into array index: %v", target, pathSeg, err)
}
if len(marray) <= index {
return nil, fmt.Errorf("failed to resolve JSON pointer: index '%v' value '%v' exceeded target array size of '%v'", target, pathSeg, len(marray))
}
object = marray[index]
} else {
return &Container{nil}, fmt.Errorf("failed to resolve JSON pointer: index '%v' field '%v' was not found", target, pathSeg)
}
}
return &Container{object}, nil
}
// S is a shorthand alias for Search.
func (g *Container) S(hierarchy ...string) *Container {
return g.Search(hierarchy...)
}
// Exists - Checks whether a path exists.
// Exists checks whether a path exists.
func (g *Container) Exists(hierarchy ...string) bool {
return g.Search(hierarchy...) != nil
}
// ExistsP - Checks whether a dot notation path exists.
// ExistsP checks whether a dot notation path exists.
func (g *Container) ExistsP(path string) bool {
return g.Exists(strings.Split(path, ".")...)
}
// Index - Attempt to find and return an object within a JSON array by index.
// Index attempts to find and return an element within a JSON array by an index.
func (g *Container) Index(index int) *Container {
if array, ok := g.Data().([]interface{}); ok {
if index >= len(array) {
@@ -146,9 +207,9 @@ func (g *Container) Index(index int) *Container {
return &Container{nil}
}
// Children - Return a slice of all the children of the array. This also works for objects, however,
// the children returned for an object will NOT be in order and you lose the names of the returned
// objects this way.
// Children returns a slice of all children of an array element. This also works
// for objects, however, the children returned for an object will be in a random
// order and you lose the names of the returned objects this way.
func (g *Container) Children() ([]*Container, error) {
if array, ok := g.Data().([]interface{}); ok {
children := make([]*Container, len(array))
@@ -167,7 +228,7 @@ func (g *Container) Children() ([]*Container, error) {
return nil, ErrNotObjOrArray
}
// ChildrenMap - Return a map of all the children of an object.
// ChildrenMap returns a map of all the children of an object element.
func (g *Container) ChildrenMap() (map[string]*Container, error) {
if mmap, ok := g.Data().(map[string]interface{}); ok {
children := map[string]*Container{}
@@ -179,11 +240,11 @@ func (g *Container) ChildrenMap() (map[string]*Container, error) {
return nil, ErrNotObj
}
//--------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Set - Set the value of a field at a JSON path, any parts of the path that do not exist will be
// constructed, and if a collision occurs with a non object type whilst iterating the path an error
// is returned.
// Set the value of a field at a JSON path, any parts of the path that do not
// exist will be constructed, and if a collision occurs with a non object type
// whilst iterating the path an error is returned.
func (g *Container) Set(value interface{}, path ...string) (*Container, error) {
if len(path) == 0 {
g.object = value
@@ -209,12 +270,14 @@ func (g *Container) Set(value interface{}, path ...string) (*Container, error) {
return &Container{object}, nil
}
// SetP - Does the same as Set, but using a dot notation JSON path.
// SetP sets the value of a field at a JSON path using dot notation, any parts
// of the path that do not exist will be constructed, and if a collision occurs
// with a non object type whilst iterating the path an error is returned.
func (g *Container) SetP(value interface{}, path string) (*Container, error) {
return g.Set(value, strings.Split(path, ".")...)
}
// SetIndex - Set a value of an array element based on the index.
// SetIndex attempts to set a value of an array element based on an index.
func (g *Container) SetIndex(value interface{}, index int) (*Container, error) {
if array, ok := g.Data().([]interface{}); ok {
if index >= len(array) {
@@ -226,60 +289,112 @@ func (g *Container) SetIndex(value interface{}, index int) (*Container, error) {
return &Container{nil}, ErrNotArray
}
// Object - Create a new JSON object at a path. Returns an error if the path contains a collision
// with a non object type.
// SetJSONPointer parses a JSON pointer path
// (https://tools.ietf.org/html/rfc6901) and sets the leaf to a value. Returns
// an error if the pointer could not be resolved due to missing fields.
func (g *Container) SetJSONPointer(value interface{}, path string) error {
hierarchy, err := resolveJSONPointerHierarchy(path)
if err != nil {
return err
}
if len(hierarchy) == 0 {
g.object = value
return nil
}
object := g.object
for target := 0; target < len(hierarchy); target++ {
pathSeg := hierarchy[target]
if mmap, ok := object.(map[string]interface{}); ok {
if target == len(hierarchy)-1 {
object = value
mmap[pathSeg] = object
} else if object = mmap[pathSeg]; object == nil {
return fmt.Errorf("failed to resolve JSON pointer: index '%v' value '%v' was not found", target, pathSeg)
}
} else if marray, ok := object.([]interface{}); ok {
index, err := strconv.Atoi(pathSeg)
if err != nil {
return fmt.Errorf("failed to resolve JSON pointer: could not parse index '%v' value '%v' into array index: %v", target, pathSeg, err)
}
if len(marray) <= index {
return fmt.Errorf("failed to resolve JSON pointer: index '%v' value '%v' exceeded target array size of '%v'", target, pathSeg, len(marray))
}
if target == len(hierarchy)-1 {
object = value
marray[index] = object
} else if object = marray[index]; object == nil {
return fmt.Errorf("failed to resolve JSON pointer: index '%v' value '%v' was not found", target, pathSeg)
}
} else {
return fmt.Errorf("failed to resolve JSON pointer: index '%v' value '%v' was not found", target, pathSeg)
}
}
return nil
}
// Object creates a new JSON object at a target path. Returns an error if the
// path contains a collision with a non object type.
func (g *Container) Object(path ...string) (*Container, error) {
return g.Set(map[string]interface{}{}, path...)
}
// ObjectP - Does the same as Object, but using a dot notation JSON path.
// ObjectP creates a new JSON object at a target path using dot notation.
// Returns an error if the path contains a collision with a non object type.
func (g *Container) ObjectP(path string) (*Container, error) {
return g.Object(strings.Split(path, ".")...)
}
// ObjectI - Create a new JSON object at an array index. Returns an error if the object is not an
// array or the index is out of bounds.
// ObjectI creates a new JSON object at an array index. Returns an error if the
// object is not an array or the index is out of bounds.
func (g *Container) ObjectI(index int) (*Container, error) {
return g.SetIndex(map[string]interface{}{}, index)
}
// Array - Create a new JSON array at a path. Returns an error if the path contains a collision with
// a non object type.
// Array creates a new JSON array at a path. Returns an error if the path
// contains a collision with a non object type.
func (g *Container) Array(path ...string) (*Container, error) {
return g.Set([]interface{}{}, path...)
}
// ArrayP - Does the same as Array, but using a dot notation JSON path.
// ArrayP creates a new JSON array at a path using dot notation. Returns an
// error if the path contains a collision with a non object type.
func (g *Container) ArrayP(path string) (*Container, error) {
return g.Array(strings.Split(path, ".")...)
}
// ArrayI - Create a new JSON array at an array index. Returns an error if the object is not an
// array or the index is out of bounds.
// ArrayI creates a new JSON array within an array at an index. Returns an error
// if the element is not an array or the index is out of bounds.
func (g *Container) ArrayI(index int) (*Container, error) {
return g.SetIndex([]interface{}{}, index)
}
// ArrayOfSize - Create a new JSON array of a particular size at a path. Returns an error if the
// path contains a collision with a non object type.
// ArrayOfSize creates a new JSON array of a particular size at a path. Returns
// an error if the path contains a collision with a non object type.
func (g *Container) ArrayOfSize(size int, path ...string) (*Container, error) {
a := make([]interface{}, size)
return g.Set(a, path...)
}
// ArrayOfSizeP - Does the same as ArrayOfSize, but using a dot notation JSON path.
// ArrayOfSizeP creates a new JSON array of a particular size at a path using
// dot notation. Returns an error if the path contains a collision with a non
// object type.
func (g *Container) ArrayOfSizeP(size int, path string) (*Container, error) {
return g.ArrayOfSize(size, strings.Split(path, ".")...)
}
// ArrayOfSizeI - Create a new JSON array of a particular size at an array index. Returns an error
// if the object is not an array or the index is out of bounds.
// ArrayOfSizeI create a new JSON array of a particular size within an array at
// an index. Returns an error if the element is not an array or the index is out
// of bounds.
func (g *Container) ArrayOfSizeI(size, index int) (*Container, error) {
a := make([]interface{}, size)
return g.SetIndex(a, index)
}
// Delete - Delete an element at a JSON path, an error is returned if the element does not exist.
// Delete an element at a path, an error is returned if the element does not
// exist.
func (g *Container) Delete(path ...string) error {
var object interface{}
@@ -304,45 +419,40 @@ func (g *Container) Delete(path ...string) error {
return nil
}
// DeleteP - Does the same as Delete, but using a dot notation JSON path.
// DeleteP deletes an element at a path using dot notation, an error is returned
// if the element does not exist.
func (g *Container) DeleteP(path string) error {
return g.Delete(strings.Split(path, ".")...)
}
// Merge - Merges two gabs-containers
func (g *Container) Merge(toMerge *Container) error {
// MergeFn merges two objects using a provided function to resolve collisions.
//
// The collision function receives two interface{} arguments, destination (the
// original object) and source (the object being merged into the destination).
// Which ever value is returned becomes the new value in the destination object
// at the location of the collision.
func (g *Container) MergeFn(source *Container, collisionFn func(destination, source interface{}) interface{}) error {
var recursiveFnc func(map[string]interface{}, []string) error
recursiveFnc = func(mmap map[string]interface{}, path []string) error {
for key, value := range mmap {
newPath := append(path, key)
if g.Exists(newPath...) {
target := g.Search(newPath...)
existingData := g.Search(newPath...).Data()
switch t := value.(type) {
case map[string]interface{}:
switch targetV := target.Data().(type) {
switch existingVal := existingData.(type) {
case map[string]interface{}:
if err := recursiveFnc(t, newPath); err != nil {
return err
}
case []interface{}:
g.Set(append(targetV, t), newPath...)
default:
newSlice := append([]interface{}{}, targetV)
g.Set(append(newSlice, t), newPath...)
}
case []interface{}:
for _, valueOfSlice := range t {
if err := g.ArrayAppend(valueOfSlice, newPath...); err != nil {
if _, err := g.Set(collisionFn(existingVal, t), newPath...); err != nil {
return err
}
}
default:
switch targetV := target.Data().(type) {
case []interface{}:
g.Set(append(targetV, t), newPath...)
default:
newSlice := append([]interface{}{}, targetV)
g.Set(append(newSlice, t), newPath...)
if _, err := g.Set(collisionFn(existingData, t), newPath...); err != nil {
return err
}
}
} else {
@@ -354,21 +464,48 @@ func (g *Container) Merge(toMerge *Container) error {
}
return nil
}
if mmap, ok := toMerge.Data().(map[string]interface{}); ok {
if mmap, ok := source.Data().(map[string]interface{}); ok {
return recursiveFnc(mmap, []string{})
}
return nil
}
//--------------------------------------------------------------------------------------------------
// Merge a source object into an existing destination object. When a collision
// is found within the merged structures (both a source and destination object
// contain the same non-object keys) the result will be an array containing both
// values, where values that are already arrays will be expanded into the
// resulting array.
//
// It is possible to merge structures will different collision behaviours with
// MergeFn.
func (g *Container) Merge(source *Container) error {
return g.MergeFn(source, func(dest, source interface{}) interface{} {
destArr, destIsArray := dest.([]interface{})
sourceArr, sourceIsArray := source.([]interface{})
if destIsArray {
if sourceIsArray {
return append(destArr, sourceArr...)
}
return append(destArr, source)
}
if sourceIsArray {
return append(append([]interface{}{}, dest), sourceArr...)
}
return []interface{}{dest, source}
})
}
//------------------------------------------------------------------------------
/*
Array modification/search - Keeping these options simple right now, no need for anything more
complicated since you can just cast to []interface{}, modify and then reassign with Set.
Array modification/search - Keeping these options simple right now, no need for
anything more complicated since you can just cast to []interface{}, modify and
then reassign with Set.
*/
// ArrayAppend - Append a value onto a JSON array. If the target is not a JSON array then it will be
// converted into one, with its contents as the first element of the array.
// ArrayAppend attempts to append a value onto a JSON array at a path. If the
// target is not a JSON array then it will be converted into one, with its
// original contents set to the first element of the array.
func (g *Container) ArrayAppend(value interface{}, path ...string) error {
if array, ok := g.Search(path...).Data().([]interface{}); ok {
array = append(array, value)
@@ -386,12 +523,15 @@ func (g *Container) ArrayAppend(value interface{}, path ...string) error {
return err
}
// ArrayAppendP - Append a value onto a JSON array using a dot notation JSON path.
// ArrayAppendP attempts to append a value onto a JSON array at a path using dot
// notation. If the target is not a JSON array then it will be converted into
// one, with its original contents set to the first element of the array.
func (g *Container) ArrayAppendP(value interface{}, path string) error {
return g.ArrayAppend(value, strings.Split(path, ".")...)
}
// ArrayRemove - Remove an element from a JSON array.
// ArrayRemove attempts to remove an element identified by an index from a JSON
// array at a path.
func (g *Container) ArrayRemove(index int, path ...string) error {
if index < 0 {
return ErrOutOfBounds
@@ -409,12 +549,14 @@ func (g *Container) ArrayRemove(index int, path ...string) error {
return err
}
// ArrayRemoveP - Remove an element from a JSON array using a dot notation JSON path.
// ArrayRemoveP attempts to remove an element identified by an index from a JSON
// array at a path using dot notation.
func (g *Container) ArrayRemoveP(index int, path string) error {
return g.ArrayRemove(index, strings.Split(path, ".")...)
}
// ArrayElement - Access an element from a JSON array.
// ArrayElement attempts to access an element by an index from a JSON array at a
// path.
func (g *Container) ArrayElement(index int, path ...string) (*Container, error) {
if index < 0 {
return &Container{nil}, ErrOutOfBounds
@@ -429,12 +571,13 @@ func (g *Container) ArrayElement(index int, path ...string) (*Container, error)
return &Container{nil}, ErrOutOfBounds
}
// ArrayElementP - Access an element from a JSON array using a dot notation JSON path.
// ArrayElementP attempts to access an element by an index from a JSON array at
// a path using dot notation.
func (g *Container) ArrayElementP(index int, path string) (*Container, error) {
return g.ArrayElement(index, strings.Split(path, ".")...)
}
// ArrayCount - Count the number of elements in a JSON array.
// ArrayCount counts the number of elements in a JSON array at a path.
func (g *Container) ArrayCount(path ...string) (int, error) {
if array, ok := g.Search(path...).Data().([]interface{}); ok {
return len(array), nil
@@ -442,14 +585,15 @@ func (g *Container) ArrayCount(path ...string) (int, error) {
return 0, ErrNotArray
}
// ArrayCountP - Count the number of elements in a JSON array using a dot notation JSON path.
// ArrayCountP counts the number of elements in a JSON array at a path using dot
// notation.
func (g *Container) ArrayCountP(path string) (int, error) {
return g.ArrayCount(strings.Split(path, ".")...)
}
//--------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Bytes - Converts the contained object back to a JSON []byte blob.
// Bytes marshals an element to a JSON []byte blob.
func (g *Container) Bytes() []byte {
if g.Data() != nil {
if bytes, err := json.Marshal(g.object); err == nil {
@@ -459,7 +603,8 @@ func (g *Container) Bytes() []byte {
return []byte("{}")
}
// BytesIndent - Converts the contained object to a JSON []byte blob formatted with prefix, indent.
// BytesIndent marshals an element to a JSON []byte blob formatted with a prefix
// and indent string.
func (g *Container) BytesIndent(prefix string, indent string) []byte {
if g.object != nil {
if bytes, err := json.MarshalIndent(g.object, prefix, indent); err == nil {
@@ -469,12 +614,13 @@ func (g *Container) BytesIndent(prefix string, indent string) []byte {
return []byte("{}")
}
// String - Converts the contained object to a JSON formatted string.
// String marshals an element to a JSON formatted string.
func (g *Container) String() string {
return string(g.Bytes())
}
// StringIndent - Converts the contained object back to a JSON formatted string with prefix, indent.
// StringIndent marshals an element to a JSON string formatted with a prefix and
// indent string.
func (g *Container) StringIndent(prefix string, indent string) string {
return string(g.BytesIndent(prefix, indent))
}
@@ -496,10 +642,9 @@ func EncodeOptIndent(prefix string, indent string) EncodeOpt {
}
}
// EncodeJSON - Encodes the contained object back to a JSON formatted []byte
// using a variant list of modifier functions for the encoder being used.
// Functions for modifying the output are prefixed with EncodeOpt, e.g.
// EncodeOptHTMLEscape.
// EncodeJSON marshals an element to a JSON formatted []byte using a variant
// list of modifier functions for the encoder being used. Functions for
// modifying the output are prefixed with EncodeOpt, e.g. EncodeOptHTMLEscape.
func (g *Container) EncodeJSON(encodeOpts ...EncodeOpt) []byte {
var b bytes.Buffer
encoder := json.NewEncoder(&b)
@@ -517,17 +662,18 @@ func (g *Container) EncodeJSON(encodeOpts ...EncodeOpt) []byte {
return result
}
// New - Create a new gabs JSON object.
// New creates a new gabs JSON object.
func New() *Container {
return &Container{map[string]interface{}{}}
}
// Consume - Gobble up an already converted JSON object, or a fresh map[string]interface{} object.
// Consume an already unmarshalled JSON object (or a new map[string]interface{})
// into a *Container.
func Consume(root interface{}) (*Container, error) {
return &Container{root}, nil
}
// ParseJSON - Convert a string into a representation of the parsed JSON.
// ParseJSON unmarshals a JSON byte slice into a *Container.
func ParseJSON(sample []byte) (*Container, error) {
var gabs Container
@@ -538,7 +684,7 @@ func ParseJSON(sample []byte) (*Container, error) {
return &gabs, nil
}
// ParseJSONDecoder - Convert a json.Decoder into a representation of the parsed JSON.
// ParseJSONDecoder applies a json.Decoder to a *Container.
func ParseJSONDecoder(decoder *json.Decoder) (*Container, error) {
var gabs Container
@@ -549,7 +695,7 @@ func ParseJSONDecoder(decoder *json.Decoder) (*Container, error) {
return &gabs, nil
}
// ParseJSONFile - Read a file and convert into a representation of the parsed JSON.
// ParseJSONFile reads a file and unmarshals the contents into a *Container.
func ParseJSONFile(path string) (*Container, error) {
if len(path) > 0 {
cBytes, err := ioutil.ReadFile(path)
@@ -567,7 +713,7 @@ func ParseJSONFile(path string) (*Container, error) {
return nil, ErrInvalidPath
}
// ParseJSONBuffer - Read the contents of a buffer into a representation of the parsed JSON.
// ParseJSONBuffer reads a buffer and unmarshals the contents into a *Container.
func ParseJSONBuffer(buffer io.Reader) (*Container, error) {
var gabs Container
jsonDecoder := json.NewDecoder(buffer)
@@ -578,4 +724,4 @@ func ParseJSONBuffer(buffer io.Reader) (*Container, error) {
return &gabs, nil
}
//--------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------

1
vendor/github.com/Jeffail/gabs/go.mod generated vendored Normal file
View File

@@ -0,0 +1 @@
module github.com/Jeffail/gabs