schemaread

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package schemaread is the one strict read every typed message uses. It takes the functions a generated table gives a caller (load, measure, the JSON reader) as a Codec, detects the form of the incoming bytes or text (binary wire by its form byte, padded standard base64 of that wire, JSON text, or a legacy text the caller recognises), measures, loads, and refuses by name what the permissive load would only count: malformed, clamped, kind_mismatch, unknown_form, wire_damaged and an absent required field. A refusal reads `<NAME> REFUSED: <reason>; run: <help>`. Unknown fields are tolerated and counted. The reader counts each read once, on the form read, in counters a caller exports. The write side runs the same bounds before a byte is written, because the generated writer checks none of them.

The package imports no generated package: the generated table functions are passed in. The rules it holds are section 4.6 of the schema-tables union research (the facade rules) and the owner's S2: text transports carry both base64 and JSON, a reader accepts either, refuses damage by name and counts reads per form.

Index

Constants

View Source
const (
	ReasonMalformed      = "malformed"
	ReasonClamped        = "clamped"
	ReasonKindMismatch   = "kind_mismatch"
	ReasonUnknownForm    = "unknown_form"
	ReasonWireDamaged    = "wire_damaged"
	ReasonAbsentRequired = "absent_required"
)

The refusal reasons, spelled as the generated tables spell them (UNION.md section 4.6).

Variables

This section is empty.

Functions

This section is empty.

Types

type Checker

type Checker struct {
	// contains filtered or unexported fields
}

Checker collects the first violation of a table's constraints.

func (*Checker) Bound

func (c *Checker) Bound(field string, v, lo, hi int64)

Bound refuses a value outside [lo, hi], the reader's clamp.

func (*Checker) Enum

func (c *Checker) Enum(field string, ordinal, count int)

Enum refuses an ordinal outside [0, count), the reader's clamp.

func (*Checker) Required

func (c *Checker) Required(field string, present bool)

Required refuses an absent field. A variable table reads an absent field as zero, so the caller says whether the read value is present (non-zero).

func (*Checker) Text

func (c *Checker) Text(field, s string, maxBytes int)

Text refuses a string over maxBytes (clamped), and one that is not UTF-8 or holds a NUL (malformed).

type Codec

type Codec[T any] struct {
	Name string // the refusal prefix, such as the message's type name
	Help string // the command a refusal points at: `run: <Help>`

	Reset func(*T) // restores the declared defaults before a load

	Forms    []byte                  // the form bytes this reader knows; empty means {1}
	Measure  func(wire []byte) error // the generated LoadMeasureReason shape; an error's text is the refusal reason
	LoadWire func(*T, []byte) Report // the generated Load over the whole wire, form byte included
	LoadJSON func(*T, []byte) Report // the generated FromJson

	Legacy     func([]byte) bool // true when the input is the caller's legacy text
	LoadLegacy func(*T, []byte) Report

	// Constraints states the bounds of the table once, for the reader and the
	// writer: it calls the Checker for each field. A violation after a load is
	// a refusal; a violation before a write refuses the write.
	Constraints func(*T, *Checker)

	SaveWire func(*T) []byte // the generated Measure and Save, returning the whole wire
	SaveJSON func(*T) []byte // the generated ToJson
}

Codec is one table's functions plus what the helper needs to refuse by name.

type Counts

type Counts struct {
	// contains filtered or unexported fields
}

Counts are the per-form read counters and the refusal and unknown-field tallies a caller exports.

func (*Counts) Names

func (c *Counts) Names() []string

Names lists the snapshot keys in order, for a stable export.

func (*Counts) Reads

func (c *Counts) Reads(f Form) uint64

Reads is the number of reads that arrived in form f.

func (*Counts) Refused

func (c *Counts) Refused(reason string) uint64

Refused is the number of reads refused with reason.

func (*Counts) Snapshot

func (c *Counts) Snapshot() map[string]uint64

Snapshot is the counters as a flat map to export: "binary", "base64", "json", "legacy", "unknown_fields" and "refused_<reason>".

func (*Counts) Unknown

func (c *Counts) Unknown() uint64

Unknown is the number of unknown fields tolerated across all reads.

type Form

type Form int

Form is the form an incoming read arrived in.

const (
	FormNone   Form = iota // nothing recognisable: refused, counted under no form
	FormBinary             // the wire, led by its form byte
	FormBase64             // padded standard base64 of the wire
	FormJSON               // the schema JSON text form
	FormLegacy             // a text the caller recognises

)

The forms a read is counted under.

func (Form) String

func (f Form) String() string

type Reader

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

Reader reads one table strictly and counts its reads.

func NewReader

func NewReader[T any](c *Codec[T]) *Reader[T]

NewReader returns a reader over c.

func (*Reader[T]) Check

func (r *Reader[T]) Check(v *T) error

Check runs the table's constraints over v: what the reader refuses after a load, the writer refuses before it writes.

func (*Reader[T]) Counts

func (r *Reader[T]) Counts() *Counts

Counts is the reader's counters.

func (*Reader[T]) Detect

func (r *Reader[T]) Detect(in []byte) Form

Detect names the form of in. Legacy text is the caller's to recognise; JSON text opens with `{`; base64 text opens with a base64 character; anything else that is not printable text is the binary wire, whose form byte the load then checks.

func (*Reader[T]) Read

func (r *Reader[T]) Read(in []byte) (T, Result, error)

Read detects the form of in, measures, loads and refuses by name. It counts the read once under the form read, whether it is refused or not. A refused read returns the zero value.

func (*Reader[T]) Write

func (r *Reader[T]) Write(v *T, form Form) ([]byte, error)

Write checks v, then writes it as form: the binary wire, padded standard base64 of the wire, or the JSON text. Nothing is written when the check refuses; legacy is read only.

type Refusal

type Refusal struct {
	Name   string
	Reason string
	Field  string // the field a constraint named, when one did
	Help   string
}

Refusal is the typed error of every refusal.

func (*Refusal) Error

func (r *Refusal) Error() string

type Report

type Report struct {
	Unknown      int    // unknown field ids skipped (newer data): tolerated, counted
	KindMismatch int    // a known id with a changed kind, skipped
	Clamped      int    // values clamped to the declared bounds
	Malformed    bool   // framing damage, decode stopped
	Reason       string // a refusal the load names itself, such as unknown_form; empty otherwise
}

Report is what a load function tells the helper, the generated TableReport reduced to the fields the strict read decides on.

type Result

type Result struct {
	Form    Form
	Unknown int // unknown fields skipped in this read
}

Result is what a successful read adds to the value.

Jump to

Keyboard shortcuts

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