diff --git a/cty/element_iterator.go b/cty/element_iterator.go index 62c9ea5..ff40007 100644 --- a/cty/element_iterator.go +++ b/cty/element_iterator.go @@ -6,16 +6,34 @@ import ( "github.com/zclconf/go-cty/cty/set" ) +// GoIter returns a [iter.Seq2[cty.Value, cty.Value]] iterator that iterates over +// the elements of a collection-typed value, yielding each element's key and +// value in turn. +// From Go 1.23, this can be used as follows: +// +// for key, val := range cty.GoIter(val) { +// // ... +// } +func GoIter(val Value) func(yield func(Value, Value) bool) { + return func(yield func(Value, Value) bool) { + for it := val.ElementIterator(); it.Next(); { + if !yield(it.Element()) { + return + } + } + } +} + // ElementIterator is the interface type returned by Value.ElementIterator to // allow the caller to iterate over elements of a collection-typed value. // // Its usage pattern is as follows: // -// it := val.ElementIterator() -// for it.Next() { -// key, val := it.Element() -// // ... -// } +// it := val.ElementIterator() +// for it.Next() { +// key, val := it.Element() +// // ... +// } type ElementIterator interface { Next() bool Element() (key Value, value Value) diff --git a/cty/element_iterator_test.go b/cty/element_iterator_test.go new file mode 100644 index 0000000..2d0712d --- /dev/null +++ b/cty/element_iterator_test.go @@ -0,0 +1,29 @@ +//go:build go1.23 + +package cty_test + +import ( + "fmt" + + "github.com/zclconf/go-cty/cty" +) + +func ExampleGoIter() { + // Test that iterating over a list works + listVal := cty.ListVal([]cty.Value{cty.NumberIntVal(1), cty.NumberIntVal(2)}) + for key, val := range cty.GoIter(listVal) { + fmt.Println(key.GoString(), val.GoString()) + } + keyVal := cty.MapVal(map[string]cty.Value{ + "a": cty.NumberIntVal(1), + "b": cty.NumberIntVal(2), + }) + for key, val := range cty.GoIter(keyVal) { + fmt.Println(key.GoString(), val.GoString()) + } + // Output: + // cty.NumberIntVal(0) cty.NumberIntVal(1) + // cty.NumberIntVal(1) cty.NumberIntVal(2) + // cty.StringVal("a") cty.NumberIntVal(1) + // cty.StringVal("b") cty.NumberIntVal(2) +}