all repos — gomponents @ 85fff9ebf5a3177d8c4e48d7314e402c0be27cee

HTML components in pure Go

Add MapIter to map over iterators

Alan Pearce
commit

85fff9ebf5a3177d8c4e48d7314e402c0be27cee

parent

7ada5cf0a0ac21780e8ef5abd4be308446fa3110

3 files changed, 47 insertions(+), 1 deletion(-)

changed files
M go.modgo.mod
@@ -1,3 +1,3 @@
module go.alanpearce.eu/gomponents -go 1.18 +go 1.23
M gomponents.gogomponents.go
@@ -22,6 +22,7 @@ import (
"fmt" "html/template" "io" + "iter" "strings" )
@@ -275,6 +276,33 @@ nodes = append(nodes, cb(k, t))
} return nodes +} + +// Map an iterator of anything to an IterNode (which is just an [iter.Seq] of [Node]-s) +func MapIter[T any](ts iter.Seq[T], cb func(T) Node) IterNode { + return IterNode{ + func(yield func(Node) bool) { + for t := range ts { + if !yield(cb(t)) { + return + } + } + }, + } +} + +type IterNode struct { + iter.Seq[Node] +} + +func (it IterNode) Render(w io.Writer) error { + for node := range it.Seq { + if err := node.Render(w); err != nil { + return err + } + } + + return nil } // Group a slice of [Node]-s into one Node, while still being usable like a regular slice of [Node]-s.
M gomponents_test.gogomponents_test.go
@@ -5,6 +5,7 @@ "errors"
"fmt" "io" "os" + "slices" "strings" "testing"
@@ -300,6 +301,23 @@ return g.El("li", g.Textf("%v: %v", key, value))
})) _ = e.Render(os.Stdout) // Output: <ul><li>party: hat</li><li>super: hat</li></ul> +} + +func TestMapIter(t *testing.T) { + items := slices.Values([]string{"party hat", "super hat"}) + e := g.El("ul", g.MapIter(items, func(value string) g.Node { + return g.El("li", g.Text(value)) + })) + assert.Equal(t, `<ul><li>party hat</li><li>super hat</li></ul>`, e) +} + +func ExampleMapIter() { + items := slices.Values([]string{"party hat", "super hat"}) + e := g.El("ul", g.MapIter(items, func(value string) g.Node { + return g.El("li", g.Text(value)) + })) + _ = e.Render(os.Stdout) + // Output: <ul><li>party hat</li><li>super hat</li></ul> } func TestGroup(t *testing.T) {