GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — nullable/nullable.go at v1.2.0 · oapi-codegen/nullable Expand file tree/ Copy pathnullable.goMore file actions 125 lines (108 loc) · 3.37 KB / Copy pathnullable.goFile metadata and controls125 lines (108 loc) · 3.37 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 package nullable import ( "bytes" "encoding/json" "errors" ) // 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 type Nullable[T any] map[bool]T // 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 func NewNullableWithValue[T any](t T) Nullable[T] { var n Nullable[T] n.Set(t) return n } // 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 func NewNullNullable[T any]() Nullable[T] { var n Nullable[T] n.SetNull() return n } // Get retrieves the underlying value, if present, and returns an error if the value was not present func (t Nullable[T]) Get() (T, error) { var empty T if t.IsNull() { return empty, errors.New("value is null") } if !t.IsSpecified() { return empty, errors.New("value is not specified") } return t[true], nil } // Dig retrieves the underlying value or returns empty value if not present or was `null`. Use Get to distinguish between these cases. func (t Nullable[T]) GetOrEmpty() T { var empty T if !t.IsSpecified() || t.IsNull() { return empty } return t[true] } func (t Nullable[T]) MustGet() T { v, err := t.Get() if err != nil { panic(err) } return v } // Set sets the underlying value to a given value func (t *Nullable[T]) Set(value T) { *t = map[bool]T{true: value} } // IsNull indicate whether the field was sent, and had a value of `null` func (t Nullable[T]) IsNull() bool { _, foundNull := t[false] return foundNull } // SetNull indicate that the field was sent, and had a value of `null` func (t *Nullable[T]) SetNull() { var empty T *t = map[bool]T{false: empty} } // IsSpecified indicates whether the field was sent func (t Nullable[T]) IsSpecified() bool { return len(t) != 0 } // SetUnspecified indicate whether the field was sent func (t *Nullable[T]) SetUnspecified() { *t = map[bool]T{} } func (t Nullable[T]) MarshalJSON() ([]byte, error) { // if field was specified, and `null`, marshal it if t.IsNull() { return []byte("null"), nil } // if field was unspecified, and `omitempty` is set on the field's tags, `json.Marshal` will omit this field // otherwise: we have a value, so marshal it return json.Marshal(t[true]) } func (t *Nullable[T]) UnmarshalJSON(data []byte) error { // if field is unspecified, UnmarshalJSON won't be called // if field is specified, and `null` if bytes.Equal(data, []byte("null")) { t.SetNull() return nil } // otherwise, we have an actual value, so parse it var v T if err := json.Unmarshal(data, &v); err != nil { return err } t.Set(v) return nil } |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |