package cliutil import ( "strconv" "time" ) // The Opt* types are flag.Value implementations that remember whether they were // given on the command line. // // They exist for PATCH: api.ProjectPatch uses a pointer per field so the server // can tell "leave this alone" from "set it to the zero value". A plain // fs.StringVar cannot express that difference — an unset --not-found-file and // an explicit --not-found-file="" both arrive as "". Each type's Ptr method // produces exactly the pointer the patch field wants. // OptString is an optional string flag. type OptString struct { Val string Present bool } func (o *OptString) String() string { if o == nil { return "" } return o.Val } func (o *OptString) Set(s string) error { o.Val, o.Present = s, true return nil } // Ptr returns nil unless the flag was given. func (o *OptString) Ptr() *string { if !o.Present { return nil } return &o.Val } // OptBool is an optional boolean flag. It may be written as --flag as well as // --flag=false. type OptBool struct { Val bool Present bool } func (o *OptBool) String() string { if o == nil { return "false" } return strconv.FormatBool(o.Val) } func (o *OptBool) Set(s string) error { v, err := strconv.ParseBool(s) if err != nil { return err } o.Val, o.Present = v, true return nil } // IsBoolFlag lets flag accept "--spa" without an explicit value. func (o *OptBool) IsBoolFlag() bool { return true } // Ptr returns nil unless the flag was given. func (o *OptBool) Ptr() *bool { if !o.Present { return nil } return &o.Val } // OptInt is an optional integer flag. type OptInt struct { Val int Present bool } func (o *OptInt) String() string { if o == nil { return "" } return strconv.Itoa(o.Val) } func (o *OptInt) Set(s string) error { v, err := strconv.Atoi(s) if err != nil { return err } o.Val, o.Present = v, true return nil } // Ptr returns nil unless the flag was given. func (o *OptInt) Ptr() *int { if !o.Present { return nil } return &o.Val } // OptBytes is an optional byte count, written as a plain number or with a unit // suffix ("256MiB"). type OptBytes struct { Val int64 Present bool } func (o *OptBytes) String() string { if o == nil { return "" } return strconv.FormatInt(o.Val, 10) } func (o *OptBytes) Set(s string) error { v, err := ParseBytes(s) if err != nil { return err } o.Val, o.Present = v, true return nil } // Ptr returns nil unless the flag was given. func (o *OptBytes) Ptr() *int64 { if !o.Present { return nil } return &o.Val } // OptDuration is an optional duration, accepting the same suffixes as // ParseDuration. type OptDuration struct { Val time.Duration Present bool } func (o *OptDuration) String() string { if o == nil { return "" } return o.Val.String() } func (o *OptDuration) Set(s string) error { v, err := ParseDuration(s) if err != nil { return err } o.Val, o.Present = v, true return nil } // SecondsPtr returns the duration in whole seconds, or nil if the flag was not // given. The API expresses grace periods as an integer number of seconds. func (o *OptDuration) SecondsPtr() *int { if !o.Present { return nil } s := int(o.Val / time.Second) return &s }