Go has a few predefined types in its flag package. How would I pass a date?
I have mimicked the URL parsing example but it looks a bit verbose and I am missing smth.
package main
import (
"flag"
"fmt"
"time"
)
const dateLayout = "2006-01-02"
type DateValue struct {
Date *time.Time
}
func (v DateValue) String() string {
if v.Date != nil {
return v.Date.Format(dateLayout)
}
return ""
}
func (v DateValue) Set(str string) error {
if t, err := time.Parse(dateLayout, str); err != nil {
return err
} else {
*v.Date = t
}
return nil
}
func main() {
var d = &time.Time{}
flag.Var(&DateValue{d}, "date", "Date part of ISO")
flag.Parse([]string{"--date", "2022-08-08"})
fmt.Printf(`{date: %q}`, d)
}
Alas, this fails with an error. You can see it at the playground
./prog.go:35:13: too many arguments in call to flag.Parse
have ([]string)
want ()
CodePudding user response:
Parse parses the command-line flags from os.Args[1:]
and needs to be called after the top level flags are defined. To build sub-commands e.g. prog --date <date-val>
, use a Flagset
.
You can notice from the method signature, that it does not take any arguments, which is the reason for your immediate error on the argument mismatch (pkg.go.dev is your friend)
With your code as shown, create a default Flagset and assign new flags and associated values
func main() {
var d = &time.Time{}
fs := flag.NewFlagSet("DateValue", flag.ExitOnError)
fs.Var(&DateValue{d}, "date", "Date part of ISO")
fs.Parse([]string{"--date", "2022-08-08"})
fmt.Printf(`{date: %q}`, d)
}