Field Types
Supported field types
The following field types are supported
[]bool[]float32[]float64[]int32[]int64[]int[]net.IP[]string[]time.Duration[]uint8[]uintboolconfigurature.ConfigFilefloat32float64int16int32int64int8intmap[string]int64map[string]intmap[string]stringnet.IPMasknet.IPNetnet.IPslog.Levelstringtime.Durationuint16uint32uint64uint8uint
As well as pointers to all of these types. Configurature also allows for adding Custom Types.
Custom Types
A custom Configurature field type specifies an exported type and how to interact with
it by satisfying Configurature’s Value interface.
type Value interface {
String() string // String representation of value
Set(string) error // Set the internal value from string
Type() string // Type name to string
}
You may be writing a custom type to configure a Go struct field type that is specific to your application or to a library used by your application.
Custom Type Example
Here is the definition of an ThumbnailFile type that only accepts
certain image file types and file size limits.
type (
// go type to be set as config struct field types
// type Config struct { FieldName ThumbnailFile `....` }
ThumbnailFile string
)
// String value of type
func (t *ThumbnailFile) String() string {
return (string)(*t)
}
// Set is always called with a string and should return an error if the string
// can not be converted to the underlying type
func (t *ThumbnailFile) Set(v string) error {
// This will fail if the file does not exist or there is any other error
// accessing the file
if st, err := os.Stat(v); err != nil {
return err
} else if st.Size() >= 5000000 {
return errors.New("file must be less than 5MB")
}
// This will fail if the file is not of the supported type
switch ext := path.Ext(strings.ToLower(v)); ext {
case ".png", ".jpg", ".jpeg", ".gif":
// ok
default:
return fmt.Errorf("file type \"%s\" not supported", ext)
}
*t = (ThumbnailFile)(v)
return nil
}
// Name of the type
func (i *ThumbnailFile) Type() string {
return "Thumbnail"
}
func init() {
// ThumbnailFile is the struct field type
configurature.AddType[ThumbnailFile]()
}
Add the type using Configurature’s AddType() function as exemplified above.
The struct field type can be used in a Configurature struct like so:
type Config struct {
ProductImage ThumbnailFile `help:"Path to thumbnail for product"`
}
This is just an example. In most cases a string field with an enum:"..."
tag will satisfy the use case. However,
if a Configurature struct field uses an app specific type, you will need
to define a custom type, use a
map value type,
or use some translation logic to convert it.
Slice of Custom Types
In order to use a slice of custom types, you will need to define a
custom type for the slice element type. For example,
if you want to use a slice of ThumbnailFile types, you will need to
define a custom type for
ThumbnailFile.
Then you can add the type to Configurature AddType[[]<CustomType>](). For example:
func init() {
configurature.AddType(ThumbnailFile)
configurature.AddType([]ThumbnailFile)
}
Important
The slice type must be added after the element type.
The struct field type can be used in a Configurature struct like so:
type Config struct {
ProductImages []ThumbnailFile `help:"Paths to thumbnails for product"`
}
Slice types are specified in CSV format for the CLI and environment variables.
$ my_app --product_images "images/side.jpg,images/top.jpg,images/bottom.jpg"
In configuration files, arrays are used.
product_images:
- images/side.jpg
- images/top.jpg
- images/bottom.jpg
Map Value Custom Types
Map value types are custom types that are used to map strings to a
custom set of values. Use AddMapValueType(typeName string, keys []string, values []T)
(usually in an init() function) to create and register these types
with configurature.
Its arguments are
typeName- The name of the type inUsage()text. Defaults to the type’s name.keys- The slice of keys to use for the map. A slice is used so that order is preserved.values- The slice of values that correspond with the keys.
See examples that follow.
Log Level Example
This is all the code
required to implement the slog.Level custom type in Configurature:
func init() {
configurature.AddMapValueType("",
[]string{
"debug",
"info",
"warn",
"error",
},
[]slog.Level{
slog.LevelDebug,
slog.LevelInfo,
slog.LevelWarn,
slog.LevelError,
},
)
}
Defining this in a config struct looks like
type Config struct {
LogLevel slog.Level `help:"Log level of app" default:"info"`
}
--log_level Level Log level (debug|info|warn|error) (default info)
Color Example
Warning
The type used in AddMapValueType can not be a type that
is already handled
by Configurature (common types like string, int, etc.). If you want to
reuse an existing type, you will have to create a new one that derives from
the existing type. E.g. type Color string below.
type Color string
func init() {
configurature.AddMapValueType("",
[]string{
"red",
"blue",
"green",
},
[]Color{
"#ff0000",
"#0000ff",
"#00ff00",
},
)
}
This can be specified on a config struct using the Color type.
type Config struct {
Background Color `help:"Color of the background" default:"red"`
Text Color `help:"Color of text" default:"blue"`
}
Delay Example
Note
In some cases, you may need to cast the value to the type. For example,
Delay(1 * time.Minute) etc. below.
// time.Duration is already registered. Use a `Delay` derived type
type Delay time.Duration
func init() {
configurature.AddMapValueType("",
[]string{
"short",
"medium",
"long",
},
[]Delay{
Delay(1 * time.Minute),
Delay(5 * time.Minute),
Delay(10 * time.Minute),
},
)
}
type Config struct {
WaitTime Delay `help:"Delay time" default:"medium"`
}
Type Name Example
Note
If the value type name is too long or otherwise undesirable, a
different type name can be specified. Below "Cluster" is specified
so that the full
type name "DeploymentClusterIdentifier" is not used.
func init() {
// "DeploymentClusterIdentifier" is a bit verbose.
// Use "Cluster" instead.
configurature.AddMapValueType("Cluster",
[]string{
"dev",
"staging",
"prod",
},
[]myapp.DeploymentClusterIdentifier{
// dev
uuid.FromString("ab0c39a5-9678-48d2-a534-7ba049988ae3"),
// staging
uuid.FromString("5ffeda13-9b47-404e-9985-12b7d77c9f5d"),
// prod
uuid.FromString("727953da-075d-4520-9aaf-9447e88f1677"),
},
)
}
type Config struct {
DeployTo DeploymentClusterIdentifier `help:"Cluster in which to deploy" default:"dev"`
}
$ myapp --help
Command usage:
--deploy_to Cluster Cluster in which to deploy (dev|staging|prod) (default dev)
-h, --help show help and exit