SkillAgentSearch skills...

Filtgen

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

Install / Use

/learn @miyamo2/Filtgen

README

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. | | `g

Related Skills

View on GitHub
GitHub Stars4
CategoryDevelopment
Updated1y ago
Forks0

Languages

Go

Security Score

75/100

Audited on Feb 18, 2025

No findings