Skip to content

Commit

Permalink
start working on flag helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
unixpickle committed Mar 31, 2024
1 parent 7c9cc22 commit d505947
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions toolbox3d/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package toolbox3d

import (
"flag"
"reflect"
"strconv"
"unicode"
)

// AddFlags adds the numeric fields of a struct to a
// FlagSet.
//
// If f is nil, the command-line FlagSet is used.
//
// Fields should be annotated with `default:...` to
// indicate the default integer or floating point values.
//
// This may panic() if the default for a field is
// incorrectly formatted.
func AddFlags(obj any, f *flag.FlagSet) {
if f == nil {
f = flag.CommandLine
}
val := reflect.ValueOf(obj)
fields := reflect.VisibleFields(val.Type())
for _, field := range fields {
flagName := flagNameForField(field.Name)
defaultStr := field.Tag.Get("default")
usageStr := field.Tag.Get("usage")
var err error
switch field.Type.Kind() {
case reflect.Int:
var defaultVal int
if defaultStr != "" {
defaultVal, err = strconv.Atoi(defaultStr)
if err != nil {
panic(err)
}
}
f.IntVar(val.FieldByIndex(field.Index).Addr().Interface().(*int),
flagName, defaultVal, usageStr)
case reflect.Float64:
var defaultVal float64
if defaultStr != "" {
defaultVal, err = strconv.ParseFloat(defaultStr, 64)
if err != nil {
panic(err)
}
}
f.Float64Var(val.FieldByIndex(field.Index).Addr().Interface().(*float64),
flagName, defaultVal, usageStr)
}
}
}

func flagNameForField(field string) string {
var result []rune
for _, x := range field {
if unicode.IsUpper(x) {
if len(result) > 0 {
result = append(result, '-')
}
result = append(result, unicode.ToLower(x))
}
}
return string(result)
}

0 comments on commit d505947

Please sign in to comment.