diff --git a/pkg/valuer/string.go b/pkg/valuer/string.go new file mode 100644 index 0000000000..18259ed0c9 --- /dev/null +++ b/pkg/valuer/string.go @@ -0,0 +1,69 @@ +package valuer + +import ( + "database/sql/driver" + "encoding/json" + "fmt" + "reflect" + "strings" +) + +var _ Valuer = (*String)(nil) + +type String struct { + val string +} + +func NewString(val string) String { + return String{val: strings.ToLower(strings.TrimSpace(val))} +} + +func (enum String) IsZero() bool { + return enum.val == "" +} + +func (enum String) StringValue() string { + return enum.val +} + +func (enum String) String() string { + return enum.val +} + +func (enum String) MarshalJSON() ([]byte, error) { + return json.Marshal(enum.StringValue()) +} + +func (enum *String) UnmarshalJSON(data []byte) error { + var str string + if err := json.Unmarshal(data, &str); err != nil { + return err + } + + *enum = NewString(str) + return nil +} + +func (enum String) Value() (driver.Value, error) { + return enum.StringValue(), nil +} + +func (enum *String) Scan(val interface{}) error { + if enum == nil { + return fmt.Errorf("string: (nil \"%s\")", reflect.TypeOf(enum).String()) + } + + if val == nil { + // Return an empty string + *enum = NewString("") + return nil + } + + str, ok := val.(string) + if !ok { + return fmt.Errorf("string: (non-string \"%s\")", reflect.TypeOf(val).String()) + } + + *enum = NewString(str) + return nil +} diff --git a/pkg/valuer/uuid.go b/pkg/valuer/uuid.go index 7c9d159b34..35b49cda8a 100644 --- a/pkg/valuer/uuid.go +++ b/pkg/valuer/uuid.go @@ -65,6 +65,10 @@ func (enum UUID) StringValue() string { return enum.val.String() } +func (enum UUID) String() string { + return enum.val.String() +} + func (enum UUID) MarshalJSON() ([]byte, error) { return json.Marshal(enum.StringValue()) } diff --git a/pkg/valuer/valuer.go b/pkg/valuer/valuer.go index 703d5b20c4..f069da04d8 100644 --- a/pkg/valuer/valuer.go +++ b/pkg/valuer/valuer.go @@ -4,19 +4,28 @@ import ( "database/sql" "database/sql/driver" "encoding/json" + "fmt" ) type Valuer interface { // IsZero returns true if the value is considered empty or zero IsZero() bool + // StringValue returns the string representation of the value StringValue() string + // MarshalJSON returns the JSON encoding of the value. json.Marshaler + // UnmarshalJSON returns the JSON decoding of the value. json.Unmarshaler + // Scan into underlying struct from a database driver's value sql.Scanner + // Convert the struct to a database driver's value driver.Valuer + + // Implement fmt.Stringer to allow the value to be printed as a string + fmt.Stringer }