| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 | package orderedmapimport (	"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 funcfunc (o *OrderedMap) SortKeys(sortFunc func(keys []string)) {	sortFunc(o.keys)}// Sort Sort the map using your sort funcfunc (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}
 |