// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. package optionalnullable import ( "bytes" "encoding/json" "reflect" ) // OptionalNullable represents a field that can distinguish between three states: // 1. Set to a value: field is present with a non-nil value // 2. Set to nil: field is present but explicitly set to null in JSON // 3. Unset: field is omitted from JSON entirely // // This type is designed to work with JSON marshaling/unmarshaling and supports // the `omitempty` struct tag to properly omit unset fields from JSON output. // // Usage: // // type User struct { // Name OptionalNullable[string] `json:"name,omitempty"` // Age OptionalNullable[int] `json:"age,omitempty"` // Tags OptionalNullable[[]string] `json:"tags,omitempty"` // } // // // Set to value // name := "John" // user.Name = From(&name) // // // Set to nil (will appear as "name": null in JSON) // user.Name = From[string](nil) // // // Leave unset (will be omitted from JSON with omitempty) // user := User{} // // WARNING: Do NOT use *OptionalNullable[T] as a field type. Always use OptionalNullable[T] directly. // Using *OptionalNullable[T] will break the omitempty behavior and JSON marshaling. // // The type is implemented as a map[bool]*T where: // - nil map represents unset state // - Map with true key represents set state (value may be nil) type OptionalNullable[T any] map[bool]*T // From creates a new OptionalNullable with the given value. // Pass nil to create a OptionalNullable that is set to null. // Pass a pointer to a value to create a OptionalNullable with that value. // // Examples: // // hello := "hello" // From(&hello) // set to "hello" // From[string](nil) // set to null func From[T any](value *T) OptionalNullable[T] { return map[bool]*T{ true: value, } } // IsNull returns true if the OptionalNullable is explicitly set to nil. // Returns false if the OptionalNullable is unset or has a value. // // Note: This differs from traditional null checks because unset fields // return false, not true. Use IsSet() to check if a field was provided. func (n OptionalNullable[T]) IsNull() bool { v, ok := n[true] return ok && v == nil } // IsSet returns true if the OptionalNullable has been explicitly set (to either a value or nil). // Returns false if the OptionalNullable is unset (omitted from JSON). // // This is the key method for distinguishing between: // - Set to nil: IsSet() = true, IsNull() = true // - Unset: IsSet() = false, IsNull() = false func (n OptionalNullable[T]) IsSet() bool { _, ok := n[true] return ok } // Get returns the internal pointer and whether the field was set. // // Return values: // - (ptr, true): field was set (ptr may be nil if set to null) // - (nil, false): field was unset/omitted // // This method provides direct access to the internal pointer representation. func (n OptionalNullable[T]) Get() (*T, bool) { v, ok := n[true] return v, ok } // GetOrZero returns the value and whether it was set. // // Return values: // - (value, true): field was set to a non-nil value // - (zero, true): field was explicitly set to nil // - (zero, false): field was unset/omitted // // Examples: // // val, ok := nullable.GetOrZero() // if !ok { // // Field was unset/omitted // } else if nullable.IsNull() { // // Field was explicitly set to null // } else { // // Field has a value: val // } func (n OptionalNullable[T]) GetOrZero() (T, bool) { var zero T if v, ok := n[true]; ok { if v == nil { return zero, true } return *v, true } return zero, false } // GetUntyped returns the value as interface{} and whether it was set. // This is useful for reflection-based code that needs to work with the value // without knowing the specific type T. // // Return values: // - (value, true): field was set to a non-nil value // - (nil, true): field was explicitly set to nil // - (nil, false): field was unset/omitted func (n OptionalNullable[T]) GetUntyped() (interface{}, bool) { if v, ok := n[true]; ok { if v == nil { return nil, true } return *v, true } return nil, false } // Set sets the OptionalNullable to the given value pointer. // Pass nil to set the field to null. // Pass a pointer to a value to set the field to that value. // // Examples: // // nullable.Set(ptrFrom("hello")) // set to "hello" // nullable.Set(nil) // set to null func (n *OptionalNullable[T]) Set(value *T) { *n = map[bool]*T{ true: value, } } // Unset removes the value, making the field unset/omitted. // After calling Unset(), IsSet() will return false and the field // will be omitted from JSON output when using omitempty. func (n *OptionalNullable[T]) Unset() { *n = map[bool]*T{} } // MarshalJSON implements json.Marshaler. // // Behavior: // - Unset fields: omitted from JSON when struct field has omitempty tag // - Null fields: serialized as "null" // - Value fields: serialized as the actual value // // The omitempty behavior works because an empty map is considered // a zero value by Go's JSON package. func (n OptionalNullable[T]) MarshalJSON() ([]byte, error) { if n.IsNull() { return []byte("null"), nil } return json.Marshal(n[true]) } // UnmarshalJSON implements json.Unmarshaler. // // Behavior: // - "null" in JSON: sets the field to null (IsSet=true, IsNull=true) // - Any other value: sets the field to that value (IsSet=true, IsNull=false) // - Missing from JSON: field remains unset (IsSet=false, IsNull=false) func (n *OptionalNullable[T]) UnmarshalJSON(data []byte) error { if bytes.Equal(data, []byte("null")) { n.Set(nil) return nil } var v T if err := json.Unmarshal(data, &v); err != nil { return err } n.Set(&v) return nil } // NullableInterface defines the interface that all OptionalNullable[T] types implement. // This interface provides untyped access to optional nullable values for reflection-based code. type OptionalNullableInterface interface { GetUntyped() (interface{}, bool) } // AsOptionalNullable attempts to convert a reflect.Value to a OptionalNullableInterface. // This is a helper function for reflection-based code that needs to check // if a value implements the optional nullable interface pattern. // // Returns: // - (nullable, true): if the value implements OptionalNullableInterface // - (nil, false): if the value does not implement OptionalNullableInterface // // Example usage: // // if nullable, ok := AsOptionalNullable(reflectValue); ok { // if value, isSet := nullable.GetUntyped(); isSet { // // Handle the nullable value // } // } func AsOptionalNullable(v reflect.Value) (OptionalNullableInterface, bool) { // Check if the value can be converted to an interface first if !v.CanInterface() { return nil, false } // Check if the underlying value is a nil map (unset nullable) if v.Kind() == reflect.Map && v.IsNil() { return nil, false } if nullable, ok := v.Interface().(OptionalNullableInterface); ok { return nullable, true } return nil, false }