mirror of https://github.com/knative/client.git
148 lines
3.6 KiB
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
|
|
}
|
|
}
|