Documentation ¶
Index ¶
- type Nullable
- func (t Nullable[T]) Get() (empty T, _ error)
- func (t Nullable[T]) IsNull() bool
- func (t Nullable[T]) IsSpecified() bool
- func (t Nullable[T]) MarshalJSON() ([]byte, error)
- func (t Nullable[T]) MustGet() T
- func (t *Nullable[T]) Scan(src any) error
- func (t *Nullable[T]) Set(value T)
- func (t *Nullable[T]) SetNull()
- func (t *Nullable[T]) SetUnspecified()
- func (t *Nullable[T]) UnmarshalJSON(data []byte) error
- func (t Nullable[T]) Value() (driver.Value, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Nullable ¶
Nullable is a generic type, which implements a field that can be one of three states:
- field is not set in the request - field is explicitly set to `null` in the request - field is explicitly set to a valid value in the request
Nullable is intended to be used with JSON marshalling and unmarshalling.
Internal implementation details:
- map[true]T means a value was provided - map[false]T means an explicit null was provided - nil or zero map means the field was not provided
If the field is expected to be optional, add the `omitempty` JSON tags. Do NOT use `*Nullable`!
Adapted from https://github.com/golang/go/issues/64515#issuecomment-1841057182
Example (MarshalOptional) ¶
package main import ( "encoding/json" "fmt" "github.com/eloonstra/nullable" ) func main() { obj := struct { ID nullable.Nullable[int] `json:"id,omitempty"` }{} // when it's not set (by default) b, err := json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Unspecified:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's not set (explicitly) obj.ID.SetUnspecified() b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Unspecified:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's set explicitly to nil obj.ID.SetNull() b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Null:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's set explicitly to the zero value var v int obj.ID.Set(v) b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Zero value:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's set explicitly to a specific value v = 12345 obj.ID.Set(v) b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Value:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") }
Output: Unspecified: JSON: {} --- Unspecified: JSON: {} --- Null: JSON: {"id":null} --- Zero value: JSON: {"id":0} --- Value: JSON: {"id":12345} ---
Example (MarshalRequired) ¶
package main import ( "encoding/json" "fmt" "github.com/eloonstra/nullable" ) func main() { obj := struct { ID nullable.Nullable[int] `json:"id"` }{} // when it's not set (by default) b, err := json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Unspecified:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's not set (explicitly) obj.ID.SetUnspecified() b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Unspecified:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's set explicitly to nil obj.ID.SetNull() b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Null:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's set explicitly to the zero value var v int obj.ID.Set(v) b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Zero value:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") // when it's set explicitly to a specific value v = 12345 obj.ID.Set(v) b, err = json.Marshal(obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Value:") fmt.Printf(`JSON: %s`+"\n", b) fmt.Println("---") }
Output: Unspecified: JSON: {"id":0} --- Unspecified: JSON: {"id":0} --- Null: JSON: {"id":null} --- Zero value: JSON: {"id":0} --- Value: JSON: {"id":12345} ---
Example (UnmarshalOptional) ¶
package main import ( "encoding/json" "fmt" "github.com/eloonstra/nullable" ) func main() { obj := struct { // Note that there is no pointer for nullable.Nullable when it's Name nullable.Nullable[string] `json:"name,omitempty"` }{} // when it's not set err := json.Unmarshal([]byte(` { } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Unspecified:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) fmt.Println("---") // when it's set explicitly to nil err = json.Unmarshal([]byte(` { "name": null } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Null:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) fmt.Println("---") // when it's set explicitly to the zero value err = json.Unmarshal([]byte(` { "name": "" } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Zero value:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) val, err := obj.Name.Get() if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("obj.Name.Get(): %#v <nil>\n", val) fmt.Printf("obj.Name.MustGet(): %#v\n", obj.Name.MustGet()) fmt.Println("---") // when it's set explicitly to a specific value err = json.Unmarshal([]byte(` { "name": "foo" } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Value:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) val, err = obj.Name.Get() if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("obj.Name.Get(): %#v <nil>\n", val) fmt.Printf("obj.Name.MustGet(): %#v\n", obj.Name.MustGet()) fmt.Println("---") }
Output: Unspecified: obj.Name.IsSpecified(): false obj.Name.IsNull(): false --- Null: obj.Name.IsSpecified(): true obj.Name.IsNull(): true --- Zero value: obj.Name.IsSpecified(): true obj.Name.IsNull(): false obj.Name.Get(): "" <nil> obj.Name.MustGet(): "" --- Value: obj.Name.IsSpecified(): true obj.Name.IsNull(): false obj.Name.Get(): "foo" <nil> obj.Name.MustGet(): "foo" ---
Example (UnmarshalRequired) ¶
package main import ( "encoding/json" "fmt" "github.com/eloonstra/nullable" ) func main() { obj := struct { Name nullable.Nullable[string] `json:"name"` }{} // when it's not set err := json.Unmarshal([]byte(` { } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Unspecified:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) fmt.Println("---") // when it's set explicitly to nil err = json.Unmarshal([]byte(` { "name": null } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Null:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) fmt.Println("---") // when it's set explicitly to the zero value err = json.Unmarshal([]byte(` { "name": "" } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Zero value:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) val, err := obj.Name.Get() if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("obj.Name.Get(): %#v <nil>\n", val) fmt.Printf("obj.Name.MustGet(): %#v\n", obj.Name.MustGet()) fmt.Println("---") // when it's set explicitly to a specific value err = json.Unmarshal([]byte(` { "name": "foo" } `), &obj) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Value:") fmt.Printf("obj.Name.IsSpecified(): %v\n", obj.Name.IsSpecified()) fmt.Printf("obj.Name.IsNull(): %v\n", obj.Name.IsNull()) val, err = obj.Name.Get() if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("obj.Name.Get(): %#v <nil>\n", val) fmt.Printf("obj.Name.MustGet(): %#v\n", obj.Name.MustGet()) fmt.Println("---") }
Output: Unspecified: obj.Name.IsSpecified(): false obj.Name.IsNull(): false --- Null: obj.Name.IsSpecified(): true obj.Name.IsNull(): true --- Zero value: obj.Name.IsSpecified(): true obj.Name.IsNull(): false obj.Name.Get(): "" <nil> obj.Name.MustGet(): "" --- Value: obj.Name.IsSpecified(): true obj.Name.IsNull(): false obj.Name.Get(): "foo" <nil> obj.Name.MustGet(): "foo" ---
func Null ¶
Null is a convenience helper to allow constructing a `Nullable` with an explicit `null`, for instance to construct a field inside a struct, without introducing an intermediate variable
func Of ¶
Of is a convenience helper to allow constructing a `Nullable` with a given value, for instance to construct a field inside a struct, without introducing an intermediate variable
func Unspecified ¶
Unspecified is a convenience helper to allow constructing a `Nullable` with an unspecified value, for instance to construct a field inside a struct, without introducing an intermediate variable
func (Nullable[T]) Get ¶
Get retrieves the underlying value, if present, and returns an error if the value was not present
func (Nullable[T]) IsSpecified ¶
IsSpecified indicates whether the field was sent
func (Nullable[T]) MarshalJSON ¶
func (Nullable[T]) MustGet ¶
func (t Nullable[T]) MustGet() T
MustGet retrieves the underlying value, if present, and panics if the value was not present
func (*Nullable[T]) Set ¶
func (t *Nullable[T]) Set(value T)
Set sets the underlying value to a given value
func (*Nullable[T]) SetNull ¶
func (t *Nullable[T]) SetNull()
SetNull indicate that the field was sent, and had a value of `null`
func (*Nullable[T]) SetUnspecified ¶
func (t *Nullable[T]) SetUnspecified()
SetUnspecified indicate whether the field was sent