Skip to content

generate an iterator by go generate that can filter by field values of the item.

License

Notifications You must be signed in to change notification settings

miyamo2/filtgen

Repository files navigation

filtgen

Go Reference GitHub go.mod Go version GitHub release (latest by date) ci Go Report Card GitHub License

CLI tool for generating iterators that selects items by their field values.

Quick Start

Install

go install github.com/miyamo2/filtgen@latest

Usage

Step 1: Tag your struct with the filtgen

//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:"*"`
}

Step 2: Run filtgen generate

Run with go generate
go generate ./...
Run with filtgen command
filtgen generate -s your_struct.go

Step 3: Use generated iterator

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.

What codes to be generated?

Types

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)
}

Methods

Following methods are generated by filtgen.

Method name is determined by the field name; e.g. Name -> NameEq.

XxxEq

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)
}

XxxNe

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)
}

XxxGt

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)
}

XxxLt

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)
}

XxxGe

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)
}

XxxLe

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)
}

XxxMatches

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)
}

XxxIs

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)
}

XxxIsnt

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)
}

List of compatible filters by type

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

filtgen tags

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.

For Contributors

Feel free to open a PR or an Issue.
However, you must promise to follow our Code of Conduct.

Tasks

We recommend that this section be run with xc.

setup:deps

Install golangci-lint.

go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

lint

golangci-lint run --fix

License

filtgen released under the MIT License