client/pkg/util/orderedmap.go

148 lines
3.6 KiB
Go

// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package util
type valueEntry struct {
Index int
Value interface{}
}
type orderedMapIterator struct {
orderedMap *OrderedMap
nextIndex int
}
// OrderedMap is similar implementation of OrderedDict in Python.
type OrderedMap struct {
Keys []string
ValueMap map[string]*valueEntry
}
// NewOrderedMap returns new empty ordered map
func NewOrderedMap() *OrderedMap {
return &OrderedMap{
Keys: []string{},
ValueMap: map[string]*valueEntry{},
}
}
// NewOrderedMapWithKVStrings returns new empty ordered map
func NewOrderedMapWithKVStrings(kvList [][]string) *OrderedMap {
o := &OrderedMap{
Keys: []string{},
ValueMap: map[string]*valueEntry{},
}
for _, pair := range kvList {
if len(pair) != 2 {
return nil
}
o.Set(pair[0], pair[1])
}
return o
}
// Get returns a value corresponding the key
func (o *OrderedMap) Get(key string) (interface{}, bool) {
ve, ok := o.ValueMap[key]
if ve != nil {
return ve.Value, ok
} else {
return nil, false
}
}
// GetString returns a string value corresponding the key
func (o *OrderedMap) GetString(key string) (string, bool) {
ve, ok := o.ValueMap[key]
if ve != nil {
return ve.Value.(string), ok
} else {
return "", false
}
}
// GetStringWithDefault returns a string value corresponding the key if the key is existing.
// Otherwise, the default value is returned.
func (o *OrderedMap) GetStringWithDefault(key string, defaultValue string) string {
if ve, ok := o.ValueMap[key]; ok {
return ve.Value.(string)
} else {
return defaultValue
}
}
// Set append the key and value if the key is not existing on the map
// Otherwise, the value does just replace the old value corresponding to the key.
func (o *OrderedMap) Set(key string, value interface{}) {
if ve, ok := o.ValueMap[key]; !ok {
o.Keys = append(o.Keys, key)
o.ValueMap[key] = &valueEntry{
Index: len(o.Keys) - 1,
Value: value,
}
} else {
ve.Value = value
}
}
// Delete deletes the key and value from the map
func (o *OrderedMap) Delete(key string) {
if ve, ok := o.ValueMap[key]; ok {
delete(o.ValueMap, key)
o.Keys = append(o.Keys[:ve.Index], o.Keys[ve.Index+1:]...)
}
}
// Len returns a size of the ordered map
func (o *OrderedMap) Len() int {
return len(o.Keys)
}
// Iterator creates a iterator object
func (o *OrderedMap) Iterator() *orderedMapIterator {
return &orderedMapIterator{
orderedMap: o,
nextIndex: 0,
}
}
// Next returns key and values on current iterating cursor.
// If the cursor moved over last entry, then the third return value will be false, otherwise true.
func (it *orderedMapIterator) Next() (string, interface{}, bool) {
if it.nextIndex >= it.orderedMap.Len() {
return "", nil, false
}
key := it.orderedMap.Keys[it.nextIndex]
ve := it.orderedMap.ValueMap[key]
it.nextIndex++
return key, ve.Value, true
}
// NextString is the same with Next, but the value is returned as string
func (it *orderedMapIterator) NextString() (string, string, bool) {
key, value, isValid := it.Next()
if isValid {
return key, value.(string), isValid
} else {
return "", "", isValid
}
}