Files
zeekayandHanzo Dev 3303b3a031 binding: gin is gone — query binding is ours
gin was in go.mod for two reflection helpers and zero routing:

  pkg/http/binding/query.go  ginbinding.MapFormWithTag
  pkg/valuer/valuer.go       ginbinding.BindUnmarshaler

BindUnmarshaler was one method; the Valuer contract now states it directly.
MapFormWithTag is reimplemented in pkg/http/binding/values.go, which is where
it belonged: a binding package should not import a web framework to reflect
over form values.

bindValues is the whole mapper. It carries exactly the semantics 20 bound
structs across this repo actually depend on, enumerated field by field:

  string · bool · int/8/16/32/64 · uint/8/16/32/64 · float32/64
  slices · pointers (nil when the key is absent, allocated when it is not)
  anonymous embedded structs, flattened into the parent namespace
  `,default=` (4 live sites: format, limit, order, orderBy)
  `-` to skip, empty tag falls back to the field name
  Unmarshaler — the one extension point, which is how every valuer enum binds

Dropped as dead weight, none of it reachable from any bound struct: map
targets, multipart, time_format/time_utc/time_location, collection_format,
the `parser` tag, arrays, and the JSON fallback for unrecognised structs.
An unsupported kind is now a named error instead of a silent JSON decode.
`required:"..."` is openapi metadata — MapFormWithTag never read it and
neither does this; a test pins that so nobody re-derives it.

Verified against the code being deleted, not asserted: a differential test
ran gin's MapFormWithTag and bindValues over all 20 real query structs plus
an every-kind fixture, 3520 input cases, comparing decoded structs and
error-ness — identical throughout. Two deliberate mutations (the empty-value
default rule, the pointer-allocation rule) turned it red, so it bites.
That harness is removed here with gin; 82 table cases stand in its place.

go mod tidy also drops goccy/go-yaml, ugorji/go/codec, pelletier/go-toml
and mongo-driver, which were gin codec plugins and nothing else.

Route table unchanged at 367. Build and full suite green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 18:23:51 -07:00

51 lines
1.3 KiB
Go

package valuer
import (
"database/sql"
"database/sql/driver"
"encoding"
"encoding/json"
"fmt"
"github.com/hanzoai/o11y/pkg/errors"
)
var (
ErrCodeUnknownValuerScan = errors.MustNewCode("unknown_valuer_scan")
ErrCodeInvalidValuer = errors.MustNewCode("invalid_valuer")
)
type Valuer interface {
// IsZero returns true if the value is considered empty or zero
IsZero() bool
// StringValue returns the string representation of the value
StringValue() string
// MarshalJSON returns the JSON encoding of the value.
json.Marshaler
// UnmarshalJSON returns the JSON decoding of the value.
json.Unmarshaler
// Scan into underlying struct from a database driver's value
sql.Scanner
// Convert the struct to a database driver's value
driver.Valuer
// Implement fmt.Stringer to allow the value to be printed as a string
fmt.Stringer
// Implement encoding.TextUnmarshaler to allow the value to be unmarshalled from a string
encoding.TextUnmarshaler
// Implement encoding.TextUnmarshaler to allow the value to be marshalled unto a string
encoding.TextMarshaler
// UnmarshalParam decodes and assigns the value from a raw form or query
// param. This is what makes every valuer bindable by pkg/http/binding,
// which asserts against it as binding.Unmarshaler.
UnmarshalParam(param string) error
}