Skip to content

Instantly share code, notes, and snippets.

@castiel
Forked from anonymous/gypsy-range.go
Last active August 29, 2015 14:06
Show Gist options
  • Save castiel/bbe12d97c82155db2fe6 to your computer and use it in GitHub Desktop.
Save castiel/bbe12d97c82155db2fe6 to your computer and use it in GitHub Desktop.
// Range runs the given closure on each element of the given list or map. If
// the directive identifies a map, idx will be 0. The index or key will be set
// to the appropriate values for a list or map, respectively, and the other
// will be zero.
//
// Example:
// config.Range("servers", func(i int, _ string, n node) {
// fmt.Printf("server[%d] = %q\n", i, n.(Scalar).String())
// })
// config.Range("users", func(_ int, name string, n node) {
// fmt.Printf("user[%q] = %#v\n", name, n)
// })
func Range(f *File, directive string, each func(idx int, key string, node yaml.Node)) error {
node, err := yaml.Child(f.Root, directive)
if err != nil {
return fmt.Errorf("no such directive: %q: %s", directive, err)
}
switch n := node.(type) {
case yaml.List:
for i, v := range n {
each(i, "", v)
}
case yaml.Map:
for k, v := range n {
each(0, k, v)
}
default:
return fmt.Errorf("%q is not a sequence or mapping (%T)", directive, n)
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment