Documentation
¶
Index ¶
- type Nullable
- func (t Nullable[T]) Get() (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]) Set(value T)
- func (t *Nullable[T]) SetNull()
- func (t *Nullable[T]) SetUnspecified()
- func (t *Nullable[T]) UnmarshalJSON(data []byte) 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/oapi-codegen/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/oapi-codegen/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/oapi-codegen/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/oapi-codegen/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 NewNullNullable ¶
NewNullNullable 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
Example ¶
package main
import (
"fmt"
"github.com/oapi-codegen/nullable"
)
func main() {
p := struct {
N nullable.Nullable[int]
}{}
p.N = nullable.NewNullNullable[int]()
fmt.Printf("Specified: %v\n", p.N.IsSpecified())
fmt.Printf("Null: %v\n", p.N.IsNull())
}
Output: Specified: true Null: true
func NewNullableWithValue ¶
NewNullableWithValue 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
Example ¶
package main
import (
"fmt"
"github.com/oapi-codegen/nullable"
)
func main() {
p := struct {
N nullable.Nullable[int]
}{}
p.N = nullable.NewNullableWithValue(123)
fmt.Println(p.N.Get())
}
Output: 123 <nil>
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 ¶ added in v1.1.0
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