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  }