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:
77
vendor/github.com/Jeffail/gabs/README.md
generated
vendored
77
vendor/github.com/Jeffail/gabs/README.md
generated
vendored
@@ -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
|
||||
|
344
vendor/github.com/Jeffail/gabs/gabs.go
generated
vendored
344
vendor/github.com/Jeffail/gabs/gabs.go
generated
vendored
@@ -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
1
vendor/github.com/Jeffail/gabs/go.mod
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module github.com/Jeffail/gabs
|
Reference in New Issue
Block a user