forked from lug/matterbridge
		
	 6ebd5cbbd8
			
		
	
	6ebd5cbbd8
	
	
	
		
			
			* Add support for editing/deleting messages * Add support for uploading files * Add support for avatars * Use the Rocket.Chat.Go.SDK * Use the rest and streaming api
		
			
				
	
	
		
			582 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			582 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright (c) 2014 Ashley Jeffs
 | |
| 
 | |
| Permission is hereby granted, free of charge, to any person obtaining a copy
 | |
| of this software and associated documentation files (the "Software"), to deal
 | |
| in the Software without restriction, including without limitation the rights
 | |
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | |
| copies of the Software, and to permit persons to whom the Software is
 | |
| furnished to do so, subject to the following conditions:
 | |
| 
 | |
| The above copyright notice and this permission notice shall be included in
 | |
| all copies or substantial portions of the Software.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| 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
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"encoding/json"
 | |
| 	"errors"
 | |
| 	"io"
 | |
| 	"io/ioutil"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| //--------------------------------------------------------------------------------------------------
 | |
| 
 | |
| var (
 | |
| 	// ErrOutOfBounds - Index out of bounds.
 | |
| 	ErrOutOfBounds = errors.New("out of bounds")
 | |
| 
 | |
| 	// ErrNotObjOrArray - The target is not an object or array type.
 | |
| 	ErrNotObjOrArray = errors.New("not an object or array")
 | |
| 
 | |
| 	// ErrNotObj - The target is not an object type.
 | |
| 	ErrNotObj = errors.New("not an object")
 | |
| 
 | |
| 	// ErrNotArray - The target is not an array type.
 | |
| 	ErrNotArray = errors.New("not an array")
 | |
| 
 | |
| 	// ErrPathCollision - 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 = errors.New("invalid input object")
 | |
| 
 | |
| 	// ErrInvalidInputText - The input data could not be parsed.
 | |
| 	ErrInvalidInputText = errors.New("input text could not be parsed")
 | |
| 
 | |
| 	// ErrInvalidPath - The filepath was not valid.
 | |
| 	ErrInvalidPath = errors.New("invalid file path")
 | |
| 
 | |
| 	// ErrInvalidBuffer - 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.
 | |
| type Container struct {
 | |
| 	object interface{}
 | |
| }
 | |
| 
 | |
| // Data - Return the contained data as an interface{}.
 | |
| func (g *Container) Data() interface{} {
 | |
| 	if g == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return g.object
 | |
| }
 | |
| 
 | |
| //--------------------------------------------------------------------------------------------------
 | |
| 
 | |
| // Path - Search for a value using 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.
 | |
| func (g *Container) Search(hierarchy ...string) *Container {
 | |
| 	var object interface{}
 | |
| 
 | |
| 	object = g.Data()
 | |
| 	for target := 0; target < len(hierarchy); target++ {
 | |
| 		if mmap, ok := object.(map[string]interface{}); ok {
 | |
| 			object, ok = mmap[hierarchy[target]]
 | |
| 			if !ok {
 | |
| 				return nil
 | |
| 			}
 | |
| 		} else if marray, ok := object.([]interface{}); ok {
 | |
| 			tmpArray := []interface{}{}
 | |
| 			for _, val := range marray {
 | |
| 				tmpGabs := &Container{val}
 | |
| 				res := tmpGabs.Search(hierarchy[target:]...)
 | |
| 				if res != nil {
 | |
| 					tmpArray = append(tmpArray, res.Data())
 | |
| 				}
 | |
| 			}
 | |
| 			if len(tmpArray) == 0 {
 | |
| 				return nil
 | |
| 			}
 | |
| 			return &Container{tmpArray}
 | |
| 		} else {
 | |
| 			return nil
 | |
| 		}
 | |
| 	}
 | |
| 	return &Container{object}
 | |
| }
 | |
| 
 | |
| // S - Shorthand method, does the same thing as Search.
 | |
| func (g *Container) S(hierarchy ...string) *Container {
 | |
| 	return g.Search(hierarchy...)
 | |
| }
 | |
| 
 | |
| // 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.
 | |
| 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.
 | |
| func (g *Container) Index(index int) *Container {
 | |
| 	if array, ok := g.Data().([]interface{}); ok {
 | |
| 		if index >= len(array) {
 | |
| 			return &Container{nil}
 | |
| 		}
 | |
| 		return &Container{array[index]}
 | |
| 	}
 | |
| 	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.
 | |
| func (g *Container) Children() ([]*Container, error) {
 | |
| 	if array, ok := g.Data().([]interface{}); ok {
 | |
| 		children := make([]*Container, len(array))
 | |
| 		for i := 0; i < len(array); i++ {
 | |
| 			children[i] = &Container{array[i]}
 | |
| 		}
 | |
| 		return children, nil
 | |
| 	}
 | |
| 	if mmap, ok := g.Data().(map[string]interface{}); ok {
 | |
| 		children := []*Container{}
 | |
| 		for _, obj := range mmap {
 | |
| 			children = append(children, &Container{obj})
 | |
| 		}
 | |
| 		return children, nil
 | |
| 	}
 | |
| 	return nil, ErrNotObjOrArray
 | |
| }
 | |
| 
 | |
| // ChildrenMap - Return a map of all the children of an object.
 | |
| func (g *Container) ChildrenMap() (map[string]*Container, error) {
 | |
| 	if mmap, ok := g.Data().(map[string]interface{}); ok {
 | |
| 		children := map[string]*Container{}
 | |
| 		for name, obj := range mmap {
 | |
| 			children[name] = &Container{obj}
 | |
| 		}
 | |
| 		return children, nil
 | |
| 	}
 | |
| 	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.
 | |
| func (g *Container) Set(value interface{}, path ...string) (*Container, error) {
 | |
| 	if len(path) == 0 {
 | |
| 		g.object = value
 | |
| 		return g, nil
 | |
| 	}
 | |
| 	var object interface{}
 | |
| 	if g.object == nil {
 | |
| 		g.object = map[string]interface{}{}
 | |
| 	}
 | |
| 	object = g.object
 | |
| 	for target := 0; target < len(path); target++ {
 | |
| 		if mmap, ok := object.(map[string]interface{}); ok {
 | |
| 			if target == len(path)-1 {
 | |
| 				mmap[path[target]] = value
 | |
| 			} else if mmap[path[target]] == nil {
 | |
| 				mmap[path[target]] = map[string]interface{}{}
 | |
| 			}
 | |
| 			object = mmap[path[target]]
 | |
| 		} else {
 | |
| 			return &Container{nil}, ErrPathCollision
 | |
| 		}
 | |
| 	}
 | |
| 	return &Container{object}, nil
 | |
| }
 | |
| 
 | |
| // SetP - Does the same as Set, but using a dot notation JSON path.
 | |
| 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.
 | |
| func (g *Container) SetIndex(value interface{}, index int) (*Container, error) {
 | |
| 	if array, ok := g.Data().([]interface{}); ok {
 | |
| 		if index >= len(array) {
 | |
| 			return &Container{nil}, ErrOutOfBounds
 | |
| 		}
 | |
| 		array[index] = value
 | |
| 		return &Container{array[index]}, nil
 | |
| 	}
 | |
| 	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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| 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.
 | |
| func (g *Container) Delete(path ...string) error {
 | |
| 	var object interface{}
 | |
| 
 | |
| 	if g.object == nil {
 | |
| 		return ErrNotObj
 | |
| 	}
 | |
| 	object = g.object
 | |
| 	for target := 0; target < len(path); target++ {
 | |
| 		if mmap, ok := object.(map[string]interface{}); ok {
 | |
| 			if target == len(path)-1 {
 | |
| 				if _, ok := mmap[path[target]]; ok {
 | |
| 					delete(mmap, path[target])
 | |
| 				} else {
 | |
| 					return ErrNotObj
 | |
| 				}
 | |
| 			}
 | |
| 			object = mmap[path[target]]
 | |
| 		} else {
 | |
| 			return ErrNotObj
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // DeleteP - Does the same as Delete, but using a dot notation JSON path.
 | |
| 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 {
 | |
| 	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...)
 | |
| 				switch t := value.(type) {
 | |
| 				case map[string]interface{}:
 | |
| 					switch targetV := target.Data().(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 {
 | |
| 							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...)
 | |
| 					}
 | |
| 				}
 | |
| 			} else {
 | |
| 				// path doesn't exist. So set the value
 | |
| 				if _, err := g.Set(value, newPath...); err != nil {
 | |
| 					return err
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return nil
 | |
| 	}
 | |
| 	if mmap, ok := toMerge.Data().(map[string]interface{}); ok {
 | |
| 		return recursiveFnc(mmap, []string{})
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| //--------------------------------------------------------------------------------------------------
 | |
| 
 | |
| /*
 | |
| 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.
 | |
| func (g *Container) ArrayAppend(value interface{}, path ...string) error {
 | |
| 	if array, ok := g.Search(path...).Data().([]interface{}); ok {
 | |
| 		array = append(array, value)
 | |
| 		_, err := g.Set(array, path...)
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	newArray := []interface{}{}
 | |
| 	if d := g.Search(path...).Data(); d != nil {
 | |
| 		newArray = append(newArray, d)
 | |
| 	}
 | |
| 	newArray = append(newArray, value)
 | |
| 
 | |
| 	_, err := g.Set(newArray, path...)
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| // ArrayAppendP - Append a value onto a JSON array using a dot notation JSON path.
 | |
| func (g *Container) ArrayAppendP(value interface{}, path string) error {
 | |
| 	return g.ArrayAppend(value, strings.Split(path, ".")...)
 | |
| }
 | |
| 
 | |
| // ArrayRemove - Remove an element from a JSON array.
 | |
| func (g *Container) ArrayRemove(index int, path ...string) error {
 | |
| 	if index < 0 {
 | |
| 		return ErrOutOfBounds
 | |
| 	}
 | |
| 	array, ok := g.Search(path...).Data().([]interface{})
 | |
| 	if !ok {
 | |
| 		return ErrNotArray
 | |
| 	}
 | |
| 	if index < len(array) {
 | |
| 		array = append(array[:index], array[index+1:]...)
 | |
| 	} else {
 | |
| 		return ErrOutOfBounds
 | |
| 	}
 | |
| 	_, err := g.Set(array, path...)
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| // ArrayRemoveP - Remove an element from a JSON array using a dot notation JSON path.
 | |
| func (g *Container) ArrayRemoveP(index int, path string) error {
 | |
| 	return g.ArrayRemove(index, strings.Split(path, ".")...)
 | |
| }
 | |
| 
 | |
| // ArrayElement - Access an element from a JSON array.
 | |
| func (g *Container) ArrayElement(index int, path ...string) (*Container, error) {
 | |
| 	if index < 0 {
 | |
| 		return &Container{nil}, ErrOutOfBounds
 | |
| 	}
 | |
| 	array, ok := g.Search(path...).Data().([]interface{})
 | |
| 	if !ok {
 | |
| 		return &Container{nil}, ErrNotArray
 | |
| 	}
 | |
| 	if index < len(array) {
 | |
| 		return &Container{array[index]}, nil
 | |
| 	}
 | |
| 	return &Container{nil}, ErrOutOfBounds
 | |
| }
 | |
| 
 | |
| // ArrayElementP - Access an element from a JSON array using a dot notation JSON path.
 | |
| 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.
 | |
| func (g *Container) ArrayCount(path ...string) (int, error) {
 | |
| 	if array, ok := g.Search(path...).Data().([]interface{}); ok {
 | |
| 		return len(array), nil
 | |
| 	}
 | |
| 	return 0, ErrNotArray
 | |
| }
 | |
| 
 | |
| // ArrayCountP - Count the number of elements in a JSON array using a dot notation JSON path.
 | |
| 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.
 | |
| func (g *Container) Bytes() []byte {
 | |
| 	if g.Data() != nil {
 | |
| 		if bytes, err := json.Marshal(g.object); err == nil {
 | |
| 			return bytes
 | |
| 		}
 | |
| 	}
 | |
| 	return []byte("{}")
 | |
| }
 | |
| 
 | |
| // BytesIndent - Converts the contained object to a JSON []byte blob formatted with prefix, indent.
 | |
| func (g *Container) BytesIndent(prefix string, indent string) []byte {
 | |
| 	if g.object != nil {
 | |
| 		if bytes, err := json.MarshalIndent(g.object, prefix, indent); err == nil {
 | |
| 			return bytes
 | |
| 		}
 | |
| 	}
 | |
| 	return []byte("{}")
 | |
| }
 | |
| 
 | |
| // String - Converts the contained object 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.
 | |
| func (g *Container) StringIndent(prefix string, indent string) string {
 | |
| 	return string(g.BytesIndent(prefix, indent))
 | |
| }
 | |
| 
 | |
| // EncodeOpt is a functional option for the EncodeJSON method.
 | |
| type EncodeOpt func(e *json.Encoder)
 | |
| 
 | |
| // EncodeOptHTMLEscape sets the encoder to escape the JSON for html.
 | |
| func EncodeOptHTMLEscape(doEscape bool) EncodeOpt {
 | |
| 	return func(e *json.Encoder) {
 | |
| 		e.SetEscapeHTML(doEscape)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // EncodeOptIndent sets the encoder to indent the JSON output.
 | |
| func EncodeOptIndent(prefix string, indent string) EncodeOpt {
 | |
| 	return func(e *json.Encoder) {
 | |
| 		e.SetIndent(prefix, indent)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // 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.
 | |
| func (g *Container) EncodeJSON(encodeOpts ...EncodeOpt) []byte {
 | |
| 	var b bytes.Buffer
 | |
| 	encoder := json.NewEncoder(&b)
 | |
| 	encoder.SetEscapeHTML(false) // Do not escape by default.
 | |
| 	for _, opt := range encodeOpts {
 | |
| 		opt(encoder)
 | |
| 	}
 | |
| 	if err := encoder.Encode(g.object); err != nil {
 | |
| 		return []byte("{}")
 | |
| 	}
 | |
| 	result := b.Bytes()
 | |
| 	if len(result) > 0 {
 | |
| 		result = result[:len(result)-1]
 | |
| 	}
 | |
| 	return result
 | |
| }
 | |
| 
 | |
| // New - Create 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.
 | |
| func Consume(root interface{}) (*Container, error) {
 | |
| 	return &Container{root}, nil
 | |
| }
 | |
| 
 | |
| // ParseJSON - Convert a string into a representation of the parsed JSON.
 | |
| func ParseJSON(sample []byte) (*Container, error) {
 | |
| 	var gabs Container
 | |
| 
 | |
| 	if err := json.Unmarshal(sample, &gabs.object); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &gabs, nil
 | |
| }
 | |
| 
 | |
| // ParseJSONDecoder - Convert a json.Decoder into a representation of the parsed JSON.
 | |
| func ParseJSONDecoder(decoder *json.Decoder) (*Container, error) {
 | |
| 	var gabs Container
 | |
| 
 | |
| 	if err := decoder.Decode(&gabs.object); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &gabs, nil
 | |
| }
 | |
| 
 | |
| // ParseJSONFile - Read a file and convert into a representation of the parsed JSON.
 | |
| func ParseJSONFile(path string) (*Container, error) {
 | |
| 	if len(path) > 0 {
 | |
| 		cBytes, err := ioutil.ReadFile(path)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		container, err := ParseJSON(cBytes)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		return container, nil
 | |
| 	}
 | |
| 	return nil, ErrInvalidPath
 | |
| }
 | |
| 
 | |
| // ParseJSONBuffer - Read the contents of a buffer into a representation of the parsed JSON.
 | |
| func ParseJSONBuffer(buffer io.Reader) (*Container, error) {
 | |
| 	var gabs Container
 | |
| 	jsonDecoder := json.NewDecoder(buffer)
 | |
| 	if err := jsonDecoder.Decode(&gabs.object); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &gabs, nil
 | |
| }
 | |
| 
 | |
| //--------------------------------------------------------------------------------------------------
 |