field

package
v1.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrExplicitNull = errors.New("this field cannot be null")

ErrExplicitNull is returned when JSON null is sent for an Optional field. The message is consumer-facing: UnmarshalJSON cannot know the field's JSON key, so callers that have the request body should use ExplicitNullField to build a parameter-specific message instead of surfacing this text directly.

Functions

func AssertValuePatchFields

func AssertValuePatchFields(typ reflect.Type)

AssertValuePatchFields panics if typ (or any embedded struct within it) declares a field.Clearable[T] or field.Optional[T] as a pointer. Both must be used as values with json:"<name>,omitzero": encoding/json short-circuits an explicit null on a pointer field to a nil pointer without calling UnmarshalJSON. For Clearable that makes "clear" indistinguishable from "unset"; for Optional it bypasses the null rejection so an explicit null is silently accepted instead of erroring. This is invoked at endpoint registration so a pointer field fails fast at startup rather than misbehaving at request time.

func EnumClearableToProto

func EnumClearableToProto[T ~string](f Clearable[T]) *pb.StringPatch

EnumClearableToProto converts a string-enum field to protobuf. Returns nil when unset. An explicitly set empty value is treated as a clear — the empty string is never a valid enum value, and spreadsheet-driven clients send "" for a blank cell.

func ExplicitNullField

func ExplicitNullField(body []byte, v any) (string, bool)

ExplicitNullField scans body for the first Optional[T] struct field whose JSON key is present and explicitly null, returning that field's JSON name. It lets a caller that holds the raw request body turn the opaque ErrExplicitNull (which has no field context, since UnmarshalJSON cannot know its own key) into a parameter-specific error. The struct shape is read from v's type; v need not be populated. Returns false when no such field is found (e.g. the null is on a nested non-embedded struct), so callers should fall back to a generic message.

func Int32ClearableToProto

func Int32ClearableToProto(f Clearable[int32]) *pb.Int32Patch

Int32ClearableToProto converts an int32 clearable field to protobuf. Returns nil when unset.

func Int32ToNullInt32

func Int32ToNullInt32(f Clearable[int32]) gosql.NullInt32

Int32ToNullInt32 maps an int32 Clearable to sql.NullInt32 for repository updates.

An unset field maps to NULL like a cleared one, so callers that mean "leave it alone" must backfill from the existing row first, the same way StringToNullString's callers do.

func IsClearableType

func IsClearableType(typ reflect.Type) bool

IsClearableType reports whether typ is field.Clearable[T] or *field.Clearable[T].

func IsOptionalType

func IsOptionalType(typ reflect.Type) bool

IsOptionalType reports whether typ is field.Optional[T] (value type only, not *Optional[T]).

func RegisterValidator

func RegisterValidator(v *validator.Validate)

RegisterValidator teaches go-playground/validator how to validate struct tags on field.Clearable[T] and field.Optional[T]: unset (and clear for Clearable) are treated as empty for validate:"omitempty"; when set, the inner value is validated.

Every concrete inner type T that carries a comparison validator (min, max, gte, lte, len, …) MUST be registered here. Without registration the validator sees the wrapper struct instead of the inner value and panics (e.g. min on a bare field.Optional[int32]). String/slice inner types only need registration so their tags are honored; the scalar numeric/bool/time types below are required to avoid that panic. Inner types defined outside this package (constants.*, request inputs) cannot be referenced here without an import cycle — those fields must rely on omitempty/required only, or register themselves from their own package.

func StringClearableToProto

func StringClearableToProto(f Clearable[string]) *pb.StringPatch

StringClearableToProto converts a string field to protobuf. Returns nil when unset.

func StringListClearableToProto

func StringListClearableToProto(f Clearable[StringList]) *pb.StringListPatch

StringListClearableToProto converts a string-list field to protobuf. Returns nil when unset.

func StringListSliceClearableToProto

func StringListSliceClearableToProto(f Clearable[[]string]) *pb.StringListPatch

StringListSliceClearableToProto converts a []string field to protobuf.

func StringToNullString

func StringToNullString(f Clearable[string]) gosql.NullString

StringToNullString maps a string Clearable to sql.NullString for repository updates.

func TimestampClearableToProto

func TimestampClearableToProto(f Clearable[time.Time]) *pb.TimestampPatch

TimestampClearableToProto converts a time.Time field to protobuf. Returns nil when unset.

Types

type Clearable

type Clearable[T any] struct {
	// contains filtered or unexported fields
}

Clearable represents a PATCH field with three states: unset (omit), clear (null), or set (value).

Use it on PATCH/update request structs as a value (Clearable[T], never *Clearable[T]) with json:"<name>,omitzero", where a caller may send a value, omit the key to leave the field unchanged, or send null to clear it. It must be a value, not a pointer: encoding/json short-circuits an explicit null on a pointer field to a nil pointer without calling UnmarshalJSON, which would make "clear" indistinguishable from "unset". As a value the addressable field's UnmarshalJSON is always invoked, so null is recorded as clear.

func Clear

func Clear[T any]() Clearable[T]

Clear returns a field explicitly set to null.

func Int32ClearableFromProto

func Int32ClearableFromProto(p *pb.Int32Patch) Clearable[int32]

Int32ClearableFromProto converts an int32 patch back to a clearable field.

func QuantityClearableFromProto

func QuantityClearableFromProto(p *pb.QuantityPatch) Clearable[QuantityInput]

QuantityClearableFromProto converts protobuf to a quantity field.

func Set

func Set[T any](v T) Clearable[T]

Set returns a field set to the given value.

func SliceClearableToStringListClearable

func SliceClearableToStringListClearable(f Clearable[[]string]) Clearable[StringList]

SliceClearableToStringListClearable converts []string patch fields for proto list patches.

func StringClearableFromProto

func StringClearableFromProto(p *pb.StringPatch) Clearable[string]

StringClearableFromProto converts protobuf to a string field. Nil means unset.

func StringListClearableFromProto

func StringListClearableFromProto(p *pb.StringListPatch) Clearable[StringList]

StringListClearableFromProto converts protobuf to a string-list field.

func TimestampClearableFromProto

func TimestampClearableFromProto(p *pb.TimestampPatch) Clearable[time.Time]

TimestampClearableFromProto converts protobuf to a time.Time field. Nil means unset.

func Unset

func Unset[T any]() Clearable[T]

Unset returns a field that was not provided in the request.

func (Clearable[T]) BackfillUnset

func (f Clearable[T]) BackfillUnset(existing T) Clearable[T]

BackfillUnset replaces unset fields with the provided existing value.

func (Clearable[T]) BackfillUnsetPtr

func (f Clearable[T]) BackfillUnsetPtr(existing *T) Clearable[T]

BackfillUnsetPtr replaces unset fields with the existing pointer value when non-nil.

func (Clearable[T]) IsClear

func (f Clearable[T]) IsClear() bool

IsClear reports whether the field was explicitly cleared.

func (Clearable[T]) IsNull

func (f Clearable[T]) IsNull() bool

IsNull reports whether the field was explicitly set to null in JSON.

func (Clearable[T]) IsSet

func (f Clearable[T]) IsSet() bool

IsSet reports whether the field has a concrete value.

func (Clearable[T]) IsUnset

func (f Clearable[T]) IsUnset() bool

IsUnset reports whether the field was absent from the request.

func (Clearable[T]) IsZero

func (f Clearable[T]) IsZero() bool

IsZero reports whether the field is unset so encoding/json omitempty omits it.

func (Clearable[T]) MarshalJSON

func (f Clearable[T]) MarshalJSON() ([]byte, error)

MarshalJSON encodes set values as JSON and clear as null. Unset fields must use json omitzero (IsZero reports unset) so they are omitted.

func (Clearable[T]) OpenAPIInnerType

func (Clearable[T]) OpenAPIInnerType() reflect.Type

OpenAPIInnerType returns the wrapped value type for OpenAPI schema generation.

func (Clearable[T]) OpenAPIKind

func (Clearable[T]) OpenAPIKind() string

OpenAPIKind identifies this type for OpenAPI generation (clearable PATCH field).

func (Clearable[string]) StringPtrAfterBackfill

func (f Clearable[string]) StringPtrAfterBackfill(existing *string) *string

StringPtrAfterBackfill returns *string for repository use after backfilling unset from existing. Clear yields nil (SQL NULL); set yields a pointer to the value.

func (*Clearable[T]) UnmarshalJSON

func (f *Clearable[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes PATCH JSON: absent keys stay unset; null clears; values set.

func (Clearable[T]) Value

func (f Clearable[T]) Value() (T, bool)

Value returns the value and true when IsSet.

func (Clearable[T]) ValuePtr

func (f Clearable[T]) ValuePtr() *T

ValuePtr returns a pointer to the value when IsSet, otherwise nil.

func (Clearable[T]) WasProvided

func (f Clearable[T]) WasProvided() bool

WasProvided reports whether the field was present in the JSON body (even if null).

type Optional

type Optional[T any] struct {
	// contains filtered or unexported fields
}

Optional is an optional request/input value: present-or-absent, never null. It is documented as nullable in OpenAPI (the value domain may be null), but an explicit JSON null is rejected at unmarshal — callers express "no value" by omitting the key. Absent keys are unset.

Use the value type on create/input request structs with json:"<field>,omitzero" (not a pointer). Do not use *Optional[T]: encoding/json would treat explicit null as a nil pointer without invoking UnmarshalJSON, so null would not be rejected.

func None

func None[T any]() Optional[T]

None returns a nullable field that was not provided in the request.

func Some

func Some[T any](v T) Optional[T]

Some returns a nullable field set to the given value.

func SomePtr

func SomePtr[T any](p *T) Optional[T]

SomePtr returns None when p is nil, otherwise Some(*p).

func (Optional[T]) IsSet

func (n Optional[T]) IsSet() bool

IsSet reports whether the field has a concrete value.

func (Optional[T]) IsUnset

func (n Optional[T]) IsUnset() bool

IsUnset reports whether the field was absent from the request.

func (Optional[T]) IsZero

func (n Optional[T]) IsZero() bool

IsZero reports whether the field is unset so encoding/json omitempty omits it.

func (Optional[T]) MarshalJSON

func (n Optional[T]) MarshalJSON() ([]byte, error)

MarshalJSON encodes set values; unset fields must use json omitempty.

func (Optional[T]) OpenAPIInnerType

func (Optional[T]) OpenAPIInnerType() reflect.Type

OpenAPIInnerType returns the wrapped value type for OpenAPI schema generation.

func (Optional[T]) OpenAPIKind

func (Optional[T]) OpenAPIKind() string

OpenAPIKind identifies this type for OpenAPI generation (nullable input, not clearable).

func (Optional[T]) Ptr

func (n Optional[T]) Ptr() *T

Ptr returns a pointer to the value when IsSet, otherwise nil.

func (*Optional[T]) UnmarshalJSON

func (n *Optional[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes JSON: null is rejected; values set the field.

func (Optional[T]) Value

func (n Optional[T]) Value() (T, bool)

Value returns the value and true when IsSet.

type QuantityInput

type QuantityInput struct {
	Value  string
	UnitID string
}

QuantityInput holds amount and unit for quantity patch fields.

type StringList

type StringList []string

StringList is a type alias so slice type parameters work with patch fields.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL