alecthomas/kongでユーザー定義型(Custom decoder)を使う

github.com

For more fine-grained control, if a field implements the MapperValue interface it will be used to decode arguments into the field.

package main

import (
    "fmt"
    "os"

    "github.com/alecthomas/kong"
)

type Foo struct {
    Value string
}

func (foo *Foo) Decode(ctx *kong.DecodeContext) error {
    var valueStr string

    // 第一引数はユーザー向けの補助情報のとのこと
    // see https://pkg.go.dev/github.com/alecthomas/kong#Scanner.PopValueInto
    // > "context" is used to assist the user if the value can not be popped, eg. "expected <context> value but got <type>"
    err := ctx.Scan.PopValueInto("foo", &valueStr)

    if err != nil {
        return err
    }

    foo.Value = valueStr

    return nil
}

func main() {
    var cli struct {
        Foo []Foo `short:"f"`
    }

    parser := kong.Must(&cli)
    _, err := parser.Parse(os.Args[1:])
    parser.FatalIfErrorf(err)

    fmt.Printf("%+v\n", cli)
}
$ go run main.go -f hello
{Foo:[{Value:hello}]}