Skip to content

flag: add TextVar to handle types that implement encoding.TextUnmarshaler #45754

@dsnet

Description

@dsnet

The encoding.TextMarshaler and encoding.TextUnmarshaler interfaces are the de-facto way for a type to self-report that it can serialize to/from some humanly readable text format.

The easiest ways to tie the flag package to encoding.TextUnmarshaler is to:

  1. use flag.Func to declare an anonymous function that calls some unmarshal function under the hood. This approach takes >3 lines, but unfortunately does not display the default value in the usage documentation.
  2. declare a type that implements flag.Value and then use flag.Var. This approach requires declaring 1 types and 2 methods and is generally more than 10 lines of cost.

Both ways have detriments (either too long or drops default values being printed).

I propose adding:

// TextVar defines a flag with a specified name, default value, and usage string.
// The argument p points to a variable in which to store the value of the flag.
// The flag accepts a value according to encoding.TextUnmarshaler.UnmarshalText.
// The default value type must be the same as the pointed at variable type.
func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string)

along with the equivalent method on the FlagSet type.

Example usage would be:

var t time.Time
flag.TextVar(&t, "start_time", time.Now(), "Time to start processing at.")

or

var n big.Int
flag.TextVar(&n, "n", big.NewInt(3853882583591558728), "Run integer factorization for this number")

Of note, this is approach only requires a single line (other than the variable declaration) and works with any type that implements encoding.TextMarshaler and encoding.TextUnmarshaler.

There is a type safety loss where the p argument and value argument may not be the same concrete type. Generics could resolve this problem.


Within the standard library, there are 5 types that implement the interfaces:

Each one could conceivably be useful to apply with the flag package.

According to the latest version of all modules, there are ~14k types that implement encoding.TextUnmarshaler out of ~8.2M types total. While this only accounts 0.2% of all types, it's still a non-trivial number of implementations.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions