blob: 9e5113a72601f7682ab637ac2b176a7049f8063a [file] [log] [blame]
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -04001// Copyright 2019 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package openapi
16
17import "encoding/json"
18
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020019// An OrderedMap is a set of key-value pairs that preserves the order in which
20// items were added. It marshals to JSON as an object.
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020021type OrderedMap struct {
22 kvs []KeyValue
23}
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040024
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020025// KeyValue associates a value with a key.
26type KeyValue struct {
27 Key string
28 Value interface{}
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040029}
30
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020031// Pairs returns the KeyValue pairs associated with m.
32func (m *OrderedMap) Pairs() []KeyValue {
33 return m.kvs
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040034}
35
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020036// Set sets a key value pair. If a pair with the same key already existed, it
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020037// will be replaced with the new value. Otherwise, the new value is added to
38// the end.
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020039func (m *OrderedMap) Set(key string, value interface{}) {
40 for i, v := range m.kvs {
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020041 if v.Key == key {
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020042 m.kvs[i].Value = value
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040043 return
44 }
45 }
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020046 m.kvs = append(m.kvs, KeyValue{key, value})
47}
48
49// SetAll replaces existing key-value pairs with the given ones. The keys must
50// be unique.
51func (m *OrderedMap) SetAll(kvs []KeyValue) {
52 m.kvs = kvs
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040053}
54
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020055// exists reports whether a key-value pair exists for the given key.
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020056func (m *OrderedMap) exists(key string) bool {
57 for _, v := range m.kvs {
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020058 if v.Key == key {
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040059 return true
60 }
61 }
62 return false
63}
64
Marcel van Lohuizen35abfa72019-08-12 15:31:53 +020065// exists reports whether a key-value pair exists for the given key.
66func (m *OrderedMap) getMap(key string) *OrderedMap {
67 for _, v := range m.kvs {
68 if v.Key == key {
69 return v.Value.(*OrderedMap)
70 }
71 }
72 return nil
73}
74
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020075// MarshalJSON implements json.Marshaler.
76func (m *OrderedMap) MarshalJSON() (b []byte, err error) {
77 // This is a pointer receiever to enforce that we only store pointers to
78 // OrderedMap in the output.
79
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040080 b = append(b, '{')
Marcel van Lohuizenc89f5a62019-07-04 10:41:18 +020081 for i, v := range m.kvs {
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040082 if i > 0 {
83 b = append(b, ",\n"...)
84 }
Marcel van Lohuizen35abfa72019-08-12 15:31:53 +020085 key, ferr := json.Marshal(v.Key)
86 if je, ok := ferr.(*json.MarshalerError); ok {
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040087 return nil, je.Err
88 }
89 b = append(b, key...)
90 b = append(b, ": "...)
91
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020092 value, jerr := json.Marshal(v.Value)
Marcel van Lohuizen35abfa72019-08-12 15:31:53 +020093 if je, ok := jerr.(*json.MarshalerError); ok {
Marcel van Lohuizen865f1592019-07-02 19:43:45 +020094 err = jerr
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -040095 value, _ = json.Marshal(je.Err.Error())
96 }
97 b = append(b, value...)
98 }
99 b = append(b, '}')
Marcel van Lohuizen865f1592019-07-02 19:43:45 +0200100 return b, err
Marcel van Lohuizenf4d483e2019-05-20 08:03:10 -0400101}