@ -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 - T he input data could not be parsed.
// ErrInvalidInputText is returned when t he input data could not be parsed.
ErrInvalidInputText = errors . New ( "input text could not be parsed" )
// ErrInvalidPath - T he filepath was not valid.
// ErrInvalidPath is returned when t he 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 c hecks 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 c hecks 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
// o bjects 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
// o rder and you lose the names of the returned o bjects 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 objec t.
// ChildrenMap returns a map of all the children of an object elemen t.
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 := toMerg e. Data ( ) . ( map [ string ] interface { } ) ; ok {
if mmap , ok := sourc e. 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 objec t to a JSON formatted string.
// String marshals an elemen t 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
}
//------------------------------------------------------------------------------ --------------------
//------------------------------------------------------------------------------