Skip to content

Commit e36f261

Browse files
committed
feat: impl GetAll and GetAllSeq
1 parent ca31a1c commit e36f261

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

cli.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ package cli
8888
import (
8989
"errors"
9090
"fmt"
91+
"iter"
9192
"os"
9293
"slices"
9394
"strings"
@@ -211,6 +212,34 @@ func GetOrFunc[T any](c *Command, id string, fn func() T) T {
211212
return fn()
212213
}
213214

215+
// GetAll returns all parsed values present for the given id. It converts each value to
216+
// the given type T through an untested type assertion (so this will panic if any value
217+
// found can't be converted to type T).
218+
func GetAll[T any](c *Command, id string) []T {
219+
vals := make([]T, 0, len(c.Inputs)/3)
220+
for i := range c.Inputs {
221+
if c.Inputs[i].ID == id {
222+
vals = append(vals, c.Inputs[i].Value.(T))
223+
}
224+
}
225+
return vals
226+
}
227+
228+
// GetAllSeq returns an iterator over each parsed value that has the given id. The
229+
// iterator yields the same values that would be returned by [GetAll](c, id) but without
230+
// constructing the slice.
231+
func GetAllSeq[T any](c *Command, id string) iter.Seq[T] {
232+
return func(yield func(T) bool) {
233+
for i := range c.Inputs {
234+
if c.Inputs[i].ID == id {
235+
if !yield(c.Inputs[i].Value.(T)) {
236+
return
237+
}
238+
}
239+
}
240+
}
241+
}
242+
214243
// ParseOrExit will parse input based on this CommandInfo. If help was requested, it
215244
// will print the help message and exit the program successfully (status code 0). If
216245
// there is any other error, it will print the error and exit the program with failure

examples_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,35 @@ func ExampleLookup_positionalArgs() {
492492
// a: "hello", true
493493
// b: "", false
494494
}
495+
496+
func ExampleGetAll() {
497+
c := cli.New().
498+
Opt(cli.NewIntOpt("a").Default("0")).
499+
ParseOrExit("-a", "1", "-a", "2", "-a", "3")
500+
501+
a := cli.GetAll[int](c, "a")
502+
503+
fmt.Printf("%+#v\n", a)
504+
// Output:
505+
// []int{0, 1, 2, 3}
506+
}
507+
508+
func ExampleGetAllSeq() {
509+
c := cli.New().
510+
Opt(cli.NewOpt("a").Default("Lorem")).
511+
ParseOrExit(
512+
"-a", "ipsum",
513+
"-a", "dolor",
514+
"-a", "sit",
515+
"-a", "amet")
516+
517+
for str := range cli.GetAllSeq[string](c, "a") {
518+
fmt.Printf("%v\n", str)
519+
}
520+
// Output:
521+
// Lorem
522+
// ipsum
523+
// dolor
524+
// sit
525+
// amet
526+
}

0 commit comments

Comments
 (0)