github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/core/elvish/eval/vals/iterate_keys.go (about) 1 package vals 2 3 import ( 4 "errors" 5 6 "github.com/u-root/u-root/cmds/core/elvish/hashmap" 7 ) 8 9 // KeysIterator wraps the IterateKeys method. 10 type KeysIterator interface { 11 // IterateKeys calls the passed function with each key within the receiver. 12 // The iteration is aborted if the function returns false. 13 IterateKeys(func(v interface{}) bool) 14 } 15 16 // IterateKeys iterates the keys of the supplied value, calling the supplied 17 // function for each key. The function can return false to break the iteration. 18 // It is implemented for the mapKeysIterable type and types satisfying the 19 // IterateKeyser interface. For these types, it always returns a nil error. For 20 // other types, it doesn't do anything and returns an error. 21 func IterateKeys(v interface{}, f func(interface{}) bool) error { 22 switch v := v.(type) { 23 case KeysIterator: 24 v.IterateKeys(f) 25 case mapKeysIterable: 26 for it := v.Iterator(); it.HasElem(); it.Next() { 27 k, _ := it.Elem() 28 if !f(k) { 29 break 30 } 31 } 32 default: 33 return errors.New(Kind(v) + " cannot have its keys iterated") 34 } 35 return nil 36 } 37 38 type mapKeysIterable interface { 39 Iterator() hashmap.Iterator 40 } 41 42 // Feed calls the function with given values, breaking earlier if the function 43 // returns false. 44 func Feed(f func(interface{}) bool, values ...interface{}) { 45 for _, value := range values { 46 if !f(value) { 47 break 48 } 49 } 50 }