github.com/sleungcy-sap/cli@v7.1.0+incompatible/util/generic/map.go (about)

     1  package generic
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  type Map interface {
     9  	IsEmpty() bool
    10  	Count() int
    11  	Keys() []interface{}
    12  	Has(key interface{}) bool
    13  	Except(keys []interface{}) Map
    14  	IsNil(key interface{}) bool
    15  	NotNil(key interface{}) bool
    16  	Get(key interface{}) interface{}
    17  	Set(key interface{}, value interface{})
    18  	Delete(key interface{})
    19  	String() string
    20  }
    21  
    22  func NewMap(data ...interface{}) Map {
    23  	if len(data) == 0 {
    24  		return newEmptyMap()
    25  	} else if len(data) > 1 {
    26  		panic("NewMap called with more than one argument")
    27  	}
    28  
    29  	switch data := data[0].(type) {
    30  	case nil:
    31  		return newEmptyMap()
    32  	case Map:
    33  		return data
    34  	case map[string]string:
    35  		stringMap := newEmptyMap()
    36  		for key, val := range data {
    37  			stringMap.Set(key, val)
    38  		}
    39  		return stringMap
    40  	case map[string]interface{}:
    41  		stringToInterfaceMap := newEmptyMap()
    42  		for key, val := range data {
    43  			stringToInterfaceMap.Set(key, val)
    44  		}
    45  		return stringToInterfaceMap
    46  	case map[interface{}]interface{}:
    47  		mapp := ConcreteMap(data)
    48  		return &mapp
    49  	}
    50  
    51  	fmt.Printf("\n\n map: %T", data)
    52  	panic("NewMap called with unexpected argument")
    53  }
    54  
    55  type Iterator func(key, val interface{})
    56  
    57  func newEmptyMap() Map {
    58  	return &ConcreteMap{}
    59  }
    60  
    61  type ConcreteMap map[interface{}]interface{}
    62  
    63  func (data *ConcreteMap) Count() int {
    64  	return len(*data)
    65  }
    66  
    67  func (data *ConcreteMap) Delete(key interface{}) {
    68  	delete(*data, key)
    69  }
    70  
    71  func (data *ConcreteMap) Except(keys []interface{}) Map {
    72  	otherMap := NewMap()
    73  	Each(data, func(key, value interface{}) {
    74  		if !Contains(keys, key) {
    75  			otherMap.Set(key, value)
    76  		}
    77  	})
    78  	return otherMap
    79  }
    80  
    81  func (data *ConcreteMap) Get(key interface{}) interface{} {
    82  	return (*data)[key]
    83  }
    84  
    85  func (data *ConcreteMap) Has(key interface{}) bool {
    86  	_, ok := (*data)[key]
    87  	return ok
    88  }
    89  
    90  func (data *ConcreteMap) IsEmpty() bool {
    91  	return data.Count() == 0
    92  }
    93  
    94  func (data *ConcreteMap) IsNil(key interface{}) bool {
    95  	maybe, ok := (*data)[key]
    96  	return ok && maybe == nil
    97  }
    98  
    99  func (data *ConcreteMap) Keys() (keys []interface{}) {
   100  	keys = make([]interface{}, 0, data.Count())
   101  	for key := range *data {
   102  		keys = append(keys, key)
   103  	}
   104  
   105  	return
   106  }
   107  
   108  func (data *ConcreteMap) NotNil(key interface{}) bool {
   109  	maybe, ok := (*data)[key]
   110  	return ok && maybe != nil
   111  }
   112  
   113  func (data *ConcreteMap) Set(key, value interface{}) {
   114  	(*data)[key] = value
   115  }
   116  
   117  func (data *ConcreteMap) String() string {
   118  	return fmt.Sprintf("% v", *data)
   119  }
   120  
   121  func Contains(collection, item interface{}) bool {
   122  	switch collection := collection.(type) {
   123  	case Map:
   124  		return collection.Has(item)
   125  	case []interface{}:
   126  		for _, val := range collection {
   127  			if val == item {
   128  				return true
   129  			}
   130  		}
   131  		return false
   132  	}
   133  
   134  	panic("unexpected type passed to Contains")
   135  }
   136  
   137  func Each(collection Map, cb Iterator) {
   138  	for _, key := range collection.Keys() {
   139  		cb(key, collection.Get(key))
   140  	}
   141  }
   142  
   143  func IsMappable(value interface{}) bool {
   144  	if value == nil {
   145  		return false
   146  	}
   147  	switch value.(type) {
   148  	case Map:
   149  		return true
   150  	default:
   151  		return reflect.TypeOf(value).Kind() == reflect.Map
   152  	}
   153  }