CLI tool for generating iterators that selects items by their field values.
go install github.com/miyamo2/filtgen@latest
//go:generate filtgen generate -s $GOFILE
package main
import (
"time"
)
type Foo struct {
StringField string `filtgen:"*"`
IntField int `filtgen:"*"`
BoolField bool `filtgen:"*"`
TimeField time.Time `filtgen:"*"`
ErrorField error `filtgen:"*"`
}
go generate ./...
filtgen generate -s your_struct.go
errSomething := errors.New("something")
s := []Foo{
{StringField: "a", IntField: 1, BoolField: true, TimeField: time.Now()},
{StringField: "b", IntField: 2, BoolField: false, TimeField: time.Now(), ErrorField: errSomething},
{StringField: "c", IntField: 3, BoolField: true, TimeField: time.Now().Add(-(time.Hour * 2))},
}
for i, v := range FooSlice(s).StringFieldGe("a") {
fmt.Printf("%d: %s\n", i, v.StringField)
}
// Output: 0: a
// 1: b
// 2: c
for i, v := range FooSlice(s).IntFieldGt(1) {
fmt.Printf("%d: %s\n", i, v.StringField)
}
// Output: 1: b
// 2: c
for i, v := range FooSlice(s).BoolFieldEq(true) {
fmt.Printf("%d: %s\n", i, v.StringField)
}
// Output: 0: a
// 2: c
for i, v := range FooSlice(s).TimeFieldMatches(func(t time.Time) bool { return t.Before(time.Now()) }) {
fmt.Printf("%d: %s\n", i, v.StringField)
}
// Output: 2: c
for i, v := range FooSlice(s).ErrorFieldIs(errSomething) {
fmt.Printf("%d: %s\n", i, v.StringField)
}
// Output: 1: b
// with method chaining
for i, v := range FooSlice(s).IntFieldGt(1).StringFieldNe("c") {
fmt.Printf("%d: %s\n", i, v.StringField)
}
// Output: 1: b
For the actual generated code, see the example.
filtgen
generates the following defined-types.
-
XxxSlice
([]T
) -
XxxMap[K]
(map[K compareble]T
) -
XxxSeq[T]
(iter.Seq[T]
) -
XxxSeq2[T]
(iter.Seq2[T, U]
)
Type name is determined by the struct name; e.g. User
-> UserSlice
.
To use the generated methods, cast must be performed.
s := []User{
{Name: "Alice"},
{Name: "Bob"},
}
for i, v := range UserSlice(s).NameEq("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Following methods are generated by filtgen
.
Method name is determined by the field name; e.g. Name
-> NameEq
.
Selects iterator items whose field values are equal to the specified value.
type User struct {
Name string `filtgen:"eq"`
}
for i, v := range UserSlice(s).NameEq("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values are not equal to the specified value.
type User struct {
Name string `filtgen:"ne"`
}
for i, v := range UserSlice(s).NameNe("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values are greater than the specified value.
type User struct {
Name string `filtgen:"gt"`
}
for i, v := range UserSlice(s).NameGt("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values are less than the specified value.
type User struct {
Name string `filtgen:"lt"`
}
for i, v := range UserSlice(s).NameLt("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values are greater than or equal to the specified value.
type User struct {
Name string `filtgen:"ge"`
}
for i, v := range UserSlice(s).NameGe("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values are less than or equal to the specified value.
type User struct {
Name string `filtgen:"le"`
}
for i, v := range UserSlice(s).NameLe("Alice") {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values match the specified function.
type User struct {
Name string `filtgen:"matches"`
}
for i, v := range UserSlice(s).NameMatches(func(s string) bool { return strings.HasPrefix(s, "A") }) {
fmt.Printf("%d: %s\n", i, v.Name)
}
Selects iterator items whose field values are equal to the specified error
.
Equivalence is determined by errors.Is
.
type Transaction struct {
ID string `filtgen:"eq"`
Err error `filtgen:"is"`
}
for i, v := range TransactionSlice(s).ErrIs(fmt.Errorf("something")) {
fmt.Printf("%d: %s\n", i, v.ID)
}
Selects iterator items whose field values are not equal to the specified error
.
Equivalence is determined by errors.Is
.
type Transaction struct {
ID string `filtgen:"eq"`
Err error `filtgen:"isnt"`
}
for i, v := range TransactionSlice(s).ErrIsnt(fmt.Errorf("something")) {
fmt.Printf("%d: %s\n", i, v.ID)
}
Type\Filter | XxxEq |
XxxNe |
XxxGt |
XxxLt |
XxxGe |
XxxLe |
XxxMatches |
XxxIs |
XxxIsnt |
---|---|---|---|---|---|---|---|---|---|
string |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
int |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
int8 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
int16 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
int32 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
int64 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
uint |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
uint8 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
uint16 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
uint32 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
uint64 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
float32 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
float64 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
complex64 |
❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
complex128 |
❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
byte |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
rune |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
error |
❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
bool |
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
other-types | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
The following values can be set in the filtgen
tag.
If you want to set multiple values, separate them with ,
.
type A struct {
StringField string `filtgen:"eq,ne"`
}
Value | Description |
---|---|
* |
Generate all methods supported according to the type of that field. |
eq |
Generate XxxEq methods. |
ne |
Generate XxxNe methods. |
gt |
Generate XxxGt methods. |
lt |
Generate XxxLt methods. |
ge |
Generate XxxGe methods. |
le |
Generate XxxLe methods. |
matches |
Generate XxxMatches methods. |
is |
Generate XxxIs methods. |
isnt |
Generate XxxIsnt methods. |
Feel free to open a PR or an Issue.
However, you must promise to follow our Code of Conduct.
We recommend that this section be run with xc
.
Install golangci-lint
.
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run --fix
filtgen released under the MIT License