Files
2026-08-15 07:13:00 +00:00

170 lines
3.2 KiB
Go

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
}