| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 | 
							- package orderedmap
 
- import (
 
- 	"bytes"
 
- 	"encoding/json"
 
- 	"sort"
 
- )
 
- type Pair struct {
 
- 	key   string
 
- 	value interface{}
 
- }
 
- func (kv *Pair) Key() string {
 
- 	return kv.key
 
- }
 
- func (kv *Pair) Value() interface{} {
 
- 	return kv.value
 
- }
 
- type ByPair struct {
 
- 	Pairs    []*Pair
 
- 	LessFunc func(a *Pair, j *Pair) bool
 
- }
 
- func (a ByPair) Len() int           { return len(a.Pairs) }
 
- func (a ByPair) Swap(i, j int)      { a.Pairs[i], a.Pairs[j] = a.Pairs[j], a.Pairs[i] }
 
- func (a ByPair) Less(i, j int) bool { return a.LessFunc(a.Pairs[i], a.Pairs[j]) }
 
- type OrderedMap struct {
 
- 	keys       []string
 
- 	values     map[string]interface{}
 
- 	escapeHTML bool
 
- }
 
- func New() *OrderedMap {
 
- 	o := OrderedMap{}
 
- 	o.keys = []string{}
 
- 	o.values = map[string]interface{}{}
 
- 	o.escapeHTML = true
 
- 	return &o
 
- }
 
- func (o *OrderedMap) SetEscapeHTML(on bool) {
 
- 	o.escapeHTML = on
 
- }
 
- func (o *OrderedMap) Get(key string) (interface{}, bool) {
 
- 	val, exists := o.values[key]
 
- 	return val, exists
 
- }
 
- func (o *OrderedMap) Set(key string, value interface{}) {
 
- 	_, exists := o.values[key]
 
- 	if !exists {
 
- 		o.keys = append(o.keys, key)
 
- 	}
 
- 	o.values[key] = value
 
- }
 
- func (o *OrderedMap) Delete(key string) {
 
- 	// check key is in use
 
- 	_, ok := o.values[key]
 
- 	if !ok {
 
- 		return
 
- 	}
 
- 	// remove from keys
 
- 	for i, k := range o.keys {
 
- 		if k == key {
 
- 			o.keys = append(o.keys[:i], o.keys[i+1:]...)
 
- 			break
 
- 		}
 
- 	}
 
- 	// remove from values
 
- 	delete(o.values, key)
 
- }
 
- func (o *OrderedMap) Keys() []string {
 
- 	return o.keys
 
- }
 
- func (o *OrderedMap) Values() map[string]interface{} {
 
- 	return o.values
 
- }
 
- // SortKeys Sort the map keys using your sort func
 
- func (o *OrderedMap) SortKeys(sortFunc func(keys []string)) {
 
- 	sortFunc(o.keys)
 
- }
 
- // Sort Sort the map using your sort func
 
- func (o *OrderedMap) Sort(lessFunc func(a *Pair, b *Pair) bool) {
 
- 	pairs := make([]*Pair, len(o.keys))
 
- 	for i, key := range o.keys {
 
- 		pairs[i] = &Pair{key, o.values[key]}
 
- 	}
 
- 	sort.Sort(ByPair{pairs, lessFunc})
 
- 	for i, pair := range pairs {
 
- 		o.keys[i] = pair.key
 
- 	}
 
- }
 
- func (o *OrderedMap) UnmarshalJSON(b []byte) error {
 
- 	if o.values == nil {
 
- 		o.values = map[string]interface{}{}
 
- 	}
 
- 	err := json.Unmarshal(b, &o.values)
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	dec := json.NewDecoder(bytes.NewReader(b))
 
- 	if _, err = dec.Token(); err != nil { // skip '{'
 
- 		return err
 
- 	}
 
- 	o.keys = make([]string, 0, len(o.values))
 
- 	return decodeOrderedMap(dec, o)
 
- }
 
- func decodeOrderedMap(dec *json.Decoder, o *OrderedMap) error {
 
- 	hasKey := make(map[string]bool, len(o.values))
 
- 	for {
 
- 		token, err := dec.Token()
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		if delim, ok := token.(json.Delim); ok && delim == '}' {
 
- 			return nil
 
- 		}
 
- 		key := token.(string)
 
- 		if hasKey[key] {
 
- 			// duplicate key
 
- 			for j, k := range o.keys {
 
- 				if k == key {
 
- 					copy(o.keys[j:], o.keys[j+1:])
 
- 					break
 
- 				}
 
- 			}
 
- 			o.keys[len(o.keys)-1] = key
 
- 		} else {
 
- 			hasKey[key] = true
 
- 			o.keys = append(o.keys, key)
 
- 		}
 
- 		token, err = dec.Token()
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		if delim, ok := token.(json.Delim); ok {
 
- 			switch delim {
 
- 			case '{':
 
- 				if values, ok := o.values[key].(map[string]interface{}); ok {
 
- 					newMap := OrderedMap{
 
- 						keys:       make([]string, 0, len(values)),
 
- 						values:     values,
 
- 						escapeHTML: o.escapeHTML,
 
- 					}
 
- 					if err = decodeOrderedMap(dec, &newMap); err != nil {
 
- 						return err
 
- 					}
 
- 					o.values[key] = newMap
 
- 				} else if oldMap, ok := o.values[key].(OrderedMap); ok {
 
- 					newMap := OrderedMap{
 
- 						keys:       make([]string, 0, len(oldMap.values)),
 
- 						values:     oldMap.values,
 
- 						escapeHTML: o.escapeHTML,
 
- 					}
 
- 					if err = decodeOrderedMap(dec, &newMap); err != nil {
 
- 						return err
 
- 					}
 
- 					o.values[key] = newMap
 
- 				} else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil {
 
- 					return err
 
- 				}
 
- 			case '[':
 
- 				if values, ok := o.values[key].([]interface{}); ok {
 
- 					if err = decodeSlice(dec, values, o.escapeHTML); err != nil {
 
- 						return err
 
- 					}
 
- 				} else if err = decodeSlice(dec, []interface{}{}, o.escapeHTML); err != nil {
 
- 					return err
 
- 				}
 
- 			}
 
- 		}
 
- 	}
 
- }
 
- func decodeSlice(dec *json.Decoder, s []interface{}, escapeHTML bool) error {
 
- 	for index := 0; ; index++ {
 
- 		token, err := dec.Token()
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		if delim, ok := token.(json.Delim); ok {
 
- 			switch delim {
 
- 			case '{':
 
- 				if index < len(s) {
 
- 					if values, ok := s[index].(map[string]interface{}); ok {
 
- 						newMap := OrderedMap{
 
- 							keys:       make([]string, 0, len(values)),
 
- 							values:     values,
 
- 							escapeHTML: escapeHTML,
 
- 						}
 
- 						if err = decodeOrderedMap(dec, &newMap); err != nil {
 
- 							return err
 
- 						}
 
- 						s[index] = newMap
 
- 					} else if oldMap, ok := s[index].(OrderedMap); ok {
 
- 						newMap := OrderedMap{
 
- 							keys:       make([]string, 0, len(oldMap.values)),
 
- 							values:     oldMap.values,
 
- 							escapeHTML: escapeHTML,
 
- 						}
 
- 						if err = decodeOrderedMap(dec, &newMap); err != nil {
 
- 							return err
 
- 						}
 
- 						s[index] = newMap
 
- 					} else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil {
 
- 						return err
 
- 					}
 
- 				} else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil {
 
- 					return err
 
- 				}
 
- 			case '[':
 
- 				if index < len(s) {
 
- 					if values, ok := s[index].([]interface{}); ok {
 
- 						if err = decodeSlice(dec, values, escapeHTML); err != nil {
 
- 							return err
 
- 						}
 
- 					} else if err = decodeSlice(dec, []interface{}{}, escapeHTML); err != nil {
 
- 						return err
 
- 					}
 
- 				} else if err = decodeSlice(dec, []interface{}{}, escapeHTML); err != nil {
 
- 					return err
 
- 				}
 
- 			case ']':
 
- 				return nil
 
- 			}
 
- 		}
 
- 	}
 
- }
 
- func (o *OrderedMap) MarshalJSON() ([]byte, error) {
 
- 	var buf bytes.Buffer
 
- 	buf.WriteByte('{')
 
- 	encoder := json.NewEncoder(&buf)
 
- 	encoder.SetEscapeHTML(o.escapeHTML)
 
- 	for i, k := range o.keys {
 
- 		if i > 0 {
 
- 			buf.WriteByte(',')
 
- 		}
 
- 		// add key
 
- 		if err := encoder.Encode(k); err != nil {
 
- 			return nil, err
 
- 		}
 
- 		buf.WriteByte(':')
 
- 		// add value
 
- 		if err := encoder.Encode(o.values[k]); err != nil {
 
- 			return nil, err
 
- 		}
 
- 	}
 
- 	buf.WriteByte('}')
 
- 	return buf.Bytes(), nil
 
- }
 
 
  |