Documentation
¶
Overview ¶
Package nullable provides a generic Value type that represents a value that may or may not be present — like sql.NullString but for any type T.
Constructing ¶
Use Of to wrap a present value and Empty to represent absence:
name := nullable.Of("alice") // valid, Val = "alice"
none := nullable.Empty[string]() // invalid (null)
FromPtr converts from pointer-based APIs (generated DTOs, ORMs) where optional fields are represented as *T:
var p *string
n := nullable.FromPtr(p) // invalid — p is nil
p = ptr.Of("alice")
n = nullable.FromPtr(p) // valid, Val = "alice"
Reading ¶
Value.Get returns the value and a boolean, similar to a map lookup:
if v, ok := name.Get(); ok {
fmt.Println(v) // "alice"
}
Value.ValueOr is a one-liner with a fallback:
display := name.ValueOr("anonymous")
Value.ToPtr converts back to a pointer — nil when invalid — for round-tripping through pointer-based APIs:
p := name.ToPtr() // *string pointing to "alice"
Value.String implements fmt.Stringer for logging and debugging:
fmt.Sprint(name) // "alice" fmt.Sprint(nullable.Empty[string]()) // "<null>"
Mutating ¶
n.Set("bob") // marks valid, sets Val
n.Clear() // marks invalid, zeroes Val
JSON ¶
Value marshals to the underlying JSON value when valid, or JSON null when not:
json.Marshal(nullable.Of("alice")) // → "alice"
json.Marshal(nullable.Empty[string]()) // → null
var n nullable.Value[string]
json.Unmarshal([]byte(`"bob"`), &n) // n.Valid=true, n.Val="bob"
json.Unmarshal([]byte(`null`), &n) // n.Valid=false
Text encoding ¶
Value implements encoding.TextMarshaler and encoding.TextUnmarshaler — an empty string round-trips as invalid (null), and any other value is formatted/parsed as text. This is what JSON map keys, [url.Values] and form/query encoders use for non-string and optional values. T must be a string, a basic numeric/bool kind, or implement the encoding.Text* interfaces itself; any other type returns an error:
nullable.Of(42).MarshalText() // → []byte("42"), nil
nullable.Empty[int]().MarshalText() // → []byte{}, nil
var n nullable.Value[int]
n.UnmarshalText([]byte("42")) // n.Valid=true, n.Val=42
n.UnmarshalText([]byte("")) // n.Valid=false
SQL ¶
Value implements sql.Scanner and driver.Valuer for use with database/sql:
var bio nullable.Value[string]
row.Scan(&bio) // NULL → bio.Valid=false; "x" → bio.Valid=true, bio.Val="x"
db.Exec("UPDATE users SET bio = ?", nullable.Of("new bio"))
db.Exec("UPDATE users SET bio = ?", nullable.Empty[string]()) // sends NULL
Equality ¶
Equal compares two Values of a comparable T:
nullable.Equal(nullable.Of(5), nullable.Of(5)) // true nullable.Equal(nullable.Empty[int](), nullable.Empty[int]()) // true — both invalid nullable.Equal(nullable.Of(5), nullable.Empty[int]()) // false
Index ¶
- func Equal[T comparable](a, b Value[T]) bool
- type Value
- func (n *Value[T]) Clear()
- func (n Value[T]) Get() (T, bool)
- func (n Value[T]) IsNull() bool
- func (n Value[T]) MarshalJSON() ([]byte, error)
- func (n Value[T]) MarshalText() ([]byte, error)
- func (n *Value[T]) Scan(src any) error
- func (n *Value[T]) Set(v T)
- func (n Value[T]) String() string
- func (n Value[T]) ToPtr() *T
- func (n *Value[T]) UnmarshalJSON(data []byte) error
- func (n *Value[T]) UnmarshalText(text []byte) error
- func (n Value[T]) Value() (driver.Value, error)
- func (n Value[T]) ValueOr(fallback T) T
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Equal ¶
func Equal[T comparable](a, b Value[T]) bool
Equal reports whether a and b represent the same optional value. Two invalid Values are equal; a valid and an invalid are not; two valid Values are equal when their underlying values are equal.
Types ¶
type Value ¶
Value holds an optional value of type T.
func FromPtr ¶
FromPtr converts a pointer to a Value. A nil pointer becomes an invalid (null) Value; a non-nil pointer becomes valid, wrapping a copy of the pointed-to value. Useful at boundaries with pointer-based APIs (generated DTOs, ORMs) that represent optional fields as *T.
func (Value[T]) MarshalJSON ¶
MarshalJSON marshals to the JSON value if valid, or null if not.
func (Value[T]) MarshalText ¶
MarshalText implements encoding.TextMarshaler. It returns an empty byte slice when invalid, or the textual representation of Val when valid — the form expected by JSON map keys, url.Values and form/query encoders. T must be a string, a basic numeric/bool kind, or implement encoding.TextMarshaler; any other type returns an error.
func (*Value[T]) Scan ¶
Scan implements sql.Scanner, allowing Value to be used as a scan destination. A nil src sets Valid=false; otherwise it delegates to sql.Scanner if T implements it, or falls back to reflect-based assignment, and sets Valid=true on success.
func (Value[T]) String ¶
String implements fmt.Stringer, returning a textual representation of Val when valid, or "<null>" when not — useful for logging and debugging.
func (Value[T]) ToPtr ¶
func (n Value[T]) ToPtr() *T
ToPtr converts n to a pointer. An invalid Value becomes nil; a valid Value becomes a pointer to a copy of Val. Pairs with FromPtr for round-tripping through pointer-based APIs.
func (*Value[T]) UnmarshalJSON ¶
UnmarshalJSON parses JSON null as invalid, otherwise unmarshals into Val and sets Valid=true.
func (*Value[T]) UnmarshalText ¶
UnmarshalText implements encoding.TextUnmarshaler. Empty input marks the Value as invalid (null); otherwise it parses the text into T. T must be a string, a basic numeric/bool kind, or *T must implement encoding.TextUnmarshaler; any other type returns an error.