Skip to content

Commit c7e1f8e

Browse files
committed
cty: add cty.GoIter for Go 1.23+
1 parent 3c2b6a0 commit c7e1f8e

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

cty/element_iterator.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,34 @@ import (
66
"github.com/zclconf/go-cty/cty/set"
77
)
88

9+
// GoIter returns a [iter.Seq2[cty.Value, cty.Value]] iterator that iterates over
10+
// the elements of a collection-typed value, yielding each element's key and
11+
// value in turn.
12+
// From Go 1.23, this can be used as follows:
13+
//
14+
// for key, val := range cty.GoIter(val) {
15+
// // ...
16+
// }
17+
func GoIter(val Value) func(yield func(Value, Value) bool) {
18+
return func(yield func(Value, Value) bool) {
19+
for it := val.ElementIterator(); it.Next(); {
20+
if !yield(it.Element()) {
21+
return
22+
}
23+
}
24+
}
25+
}
26+
927
// ElementIterator is the interface type returned by Value.ElementIterator to
1028
// allow the caller to iterate over elements of a collection-typed value.
1129
//
1230
// Its usage pattern is as follows:
1331
//
14-
// it := val.ElementIterator()
15-
// for it.Next() {
16-
// key, val := it.Element()
17-
// // ...
18-
// }
32+
// it := val.ElementIterator()
33+
// for it.Next() {
34+
// key, val := it.Element()
35+
// // ...
36+
// }
1937
type ElementIterator interface {
2038
Next() bool
2139
Element() (key Value, value Value)

cty/element_iterator_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//go:build go1.23
2+
3+
package cty_test
4+
5+
import (
6+
"fmt"
7+
8+
"github.com/zclconf/go-cty/cty"
9+
)
10+
11+
func ExampleGoIter() {
12+
// Test that iterating over a list works
13+
listVal := cty.ListVal([]cty.Value{cty.NumberIntVal(1), cty.NumberIntVal(2)})
14+
for key, val := range cty.GoIter(listVal) {
15+
fmt.Println(key.GoString(), val.GoString())
16+
}
17+
keyVal := cty.MapVal(map[string]cty.Value{
18+
"a": cty.NumberIntVal(1),
19+
"b": cty.NumberIntVal(2),
20+
})
21+
for key, val := range cty.GoIter(keyVal) {
22+
fmt.Println(key.GoString(), val.GoString())
23+
}
24+
// Output:
25+
// cty.NumberIntVal(0) cty.NumberIntVal(1)
26+
// cty.NumberIntVal(1) cty.NumberIntVal(2)
27+
// cty.StringVal("a") cty.NumberIntVal(1)
28+
// cty.StringVal("b") cty.NumberIntVal(2)
29+
}

0 commit comments

Comments
 (0)