[WIP] Initial commit
This commit is contained in:
167
vendor/github.com/hjson/hjson-go/v4/orderedmap.go
generated
vendored
Normal file
167
vendor/github.com/hjson/hjson-go/v4/orderedmap.go
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
package hjson
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// OrderedMap wraps a map and a slice containing all of the keys from the map,
|
||||
// so that the order of the keys can be specified. The Keys slice can be sorted
|
||||
// or rearranged like any other slice, but do not add or remove keys manually
|
||||
// on it. Use OrderedMap.Insert(), OrderedMap.Set(), OrderedMap.DeleteIndex() or
|
||||
// OrderedMap.DeleteKey() instead.
|
||||
//
|
||||
// Example of how to iterate through the elements of an OrderedMap in order:
|
||||
//
|
||||
// for _, key := range om.Keys {
|
||||
// fmt.Printf("%v\n", om.Map[key])
|
||||
// }
|
||||
//
|
||||
// Always use the functions Insert() or Set() instead of setting values
|
||||
// directly on OrderedMap.Map, because any new keys must also be added to
|
||||
// OrderedMap.Keys. Otherwise those keys will be ignored when iterating through
|
||||
// the elements of the OrderedMap in order, as for example happens in the
|
||||
// function hjson.Marshal().
|
||||
type OrderedMap struct {
|
||||
Keys []string
|
||||
Map map[string]interface{}
|
||||
}
|
||||
|
||||
// KeyValue is only used as input to NewOrderedMapFromSlice().
|
||||
type KeyValue struct {
|
||||
Key string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// NewOrderedMap returns a pointer to a new OrderedMap. An OrderedMap should
|
||||
// always be passed by reference, never by value. If an OrderedMap is passed
|
||||
// by value then appending new keys won't affect all of the copies of the
|
||||
// OrderedMap.
|
||||
func NewOrderedMap() *OrderedMap {
|
||||
return &OrderedMap{
|
||||
Keys: nil,
|
||||
Map: map[string]interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewOrderedMapFromSlice is like NewOrderedMap but with initial values.
|
||||
// Example:
|
||||
//
|
||||
// om := NewOrderedMapFromSlice([]KeyValue{
|
||||
// {"B", "first"},
|
||||
// {"A", "second"},
|
||||
// })
|
||||
func NewOrderedMapFromSlice(args []KeyValue) *OrderedMap {
|
||||
c := NewOrderedMap()
|
||||
for _, elem := range args {
|
||||
c.Set(elem.Key, elem.Value)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Len returns the number of values contained in the OrderedMap.
|
||||
func (c *OrderedMap) Len() int {
|
||||
return len(c.Keys)
|
||||
}
|
||||
|
||||
// AtIndex returns the value found at the specified index. Panics if
|
||||
// index < 0 or index >= c.Len().
|
||||
func (c *OrderedMap) AtIndex(index int) interface{} {
|
||||
return c.Map[c.Keys[index]]
|
||||
}
|
||||
|
||||
// AtKey returns the value found for the specified key, and true if the value
|
||||
// was found. Returns nil and false if the value was not found.
|
||||
func (c *OrderedMap) AtKey(key string) (interface{}, bool) {
|
||||
ret, ok := c.Map[key]
|
||||
return ret, ok
|
||||
}
|
||||
|
||||
// Insert inserts a new key/value pair at the specified index. Panics if
|
||||
// index < 0 or index > c.Len(). If the key already exists in the OrderedMap,
|
||||
// the new value is set but the position of the key is not changed. Returns
|
||||
// the old value and true if the key already exists in the OrderedMap, nil and
|
||||
// false otherwise.
|
||||
func (c *OrderedMap) Insert(index int, key string, value interface{}) (interface{}, bool) {
|
||||
oldValue, exists := c.Map[key]
|
||||
c.Map[key] = value
|
||||
if exists {
|
||||
return oldValue, true
|
||||
}
|
||||
if index == len(c.Keys) {
|
||||
c.Keys = append(c.Keys, key)
|
||||
} else {
|
||||
c.Keys = append(c.Keys[:index+1], c.Keys[index:]...)
|
||||
c.Keys[index] = key
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Set sets the specified value for the specified key. If the key does not
|
||||
// already exist in the OrderedMap it is appended to the end of the OrderedMap.
|
||||
// If the key already exists in the OrderedMap, the new value is set but the
|
||||
// position of the key is not changed. Returns the old value and true if the
|
||||
// key already exists in the OrderedMap, nil and false otherwise.
|
||||
func (c *OrderedMap) Set(key string, value interface{}) (interface{}, bool) {
|
||||
return c.Insert(len(c.Keys), key, value)
|
||||
}
|
||||
|
||||
// DeleteIndex deletes the key/value pair found at the specified index.
|
||||
// Returns the deleted key and value. Panics if index < 0 or index >= c.Len().
|
||||
func (c *OrderedMap) DeleteIndex(index int) (string, interface{}) {
|
||||
key := c.Keys[index]
|
||||
value := c.Map[key]
|
||||
delete(c.Map, key)
|
||||
c.Keys = append(c.Keys[:index], c.Keys[index+1:]...)
|
||||
return key, value
|
||||
}
|
||||
|
||||
// DeleteKey deletes the key/value pair with the specified key, if found.
|
||||
// Returns the deleted value and true if the key was found, nil and false
|
||||
// otherwise.
|
||||
func (c *OrderedMap) DeleteKey(key string) (interface{}, bool) {
|
||||
for index, ck := range c.Keys {
|
||||
if ck == key {
|
||||
_, value := c.DeleteIndex(index)
|
||||
return value, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// MarshalJSON is an implementation of the json.Marshaler interface, enabling
|
||||
// hjson.OrderedMap to be used as input for json.Marshal().
|
||||
func (c *OrderedMap) MarshalJSON() ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
|
||||
b.WriteString("{")
|
||||
|
||||
for index, key := range c.Keys {
|
||||
if index > 0 {
|
||||
b.WriteString(",")
|
||||
}
|
||||
jbuf, err := json.Marshal(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Write(jbuf)
|
||||
b.WriteString(":")
|
||||
jbuf, err = json.Marshal(c.Map[key])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Write(jbuf)
|
||||
}
|
||||
|
||||
b.WriteString("}")
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON is an implementation of the json.Unmarshaler interface,
|
||||
// enabling hjson.OrderedMap to be used as destination for json.Unmarshal().
|
||||
func (c *OrderedMap) UnmarshalJSON(b []byte) error {
|
||||
c.Keys = nil
|
||||
c.Map = map[string]interface{}{}
|
||||
return Unmarshal(b, c)
|
||||
}
|
||||
Reference in New Issue
Block a user