zfs.NilBool: document its purpose and move it to its own package 'nodefault'
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
// Package nodefault provides newtypes around builtin Go types
|
||||
// so that if the newtype is used as a field in a struct and that field
|
||||
// is zero-initialized (https://golang.org/ref/spec#The_zero_value),
|
||||
// accessing the field will cause a null pointer deref panic.
|
||||
// Or in other terms: It soft-enforces that the caller sets the field
|
||||
// explicitly when constructing the struct.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// type Config struct {
|
||||
// // This field must be set to a non-nil value,
|
||||
// // forcing the caller to make their mind up
|
||||
// // about this field.
|
||||
// CriticalSetting *nodefault.Bool
|
||||
// }
|
||||
//
|
||||
// An function that takes such a Config should _not_ check for nil-ness:
|
||||
// and instead unconditionally dereference:
|
||||
//
|
||||
// func f(c Config) {
|
||||
// if (c.CriticalSetting) { }
|
||||
// }
|
||||
//
|
||||
// If the caller of f forgot to specify the .CriticalSetting
|
||||
// field, the Go runtime will issue a nil-pointer deref panic
|
||||
// and it'll be clear that the caller did not read the docs of Config.
|
||||
//
|
||||
// f(Config{}) // crashes
|
||||
//
|
||||
// f Config{ CriticalSetting: &nodefault.Bool{B: false}} // doesn't crash
|
||||
//
|
||||
package nodefault
|
||||
@@ -0,0 +1,19 @@
|
||||
package nodefault
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Bool struct{ B bool }
|
||||
|
||||
func (n *Bool) ValidateNoDefault() error {
|
||||
if n == nil {
|
||||
return fmt.Errorf("must explicitly set `true` or `false`")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Bool) String() string {
|
||||
if n == nil {
|
||||
return "unset"
|
||||
}
|
||||
return fmt.Sprintf("%v", n.B)
|
||||
}
|
||||
Reference in New Issue
Block a user