Documentation
¶
Overview ¶
Package dryvalidation is a pure-Go (CGO-free) MRI-faithful reimplementation of Ruby's dry-schema and dry-validation gems: a schema/contract DSL that coerces and validates a hash of input against key-presence rules, value macros (filled/maybe/value/each/array/hash/schema), dry-types coercion and dry-logic predicate constraints, then reports a nested errors hash whose messages are byte-identical to the gems' default English (en) locale.
The type layer under every schema key is the sibling package github.com/go-ruby-dry-types/dry-types: a schema key's coercion+constraint is a dry-types drytypes.Type, and the schema composes those into a whole-hash validator.
Ruby value model ¶
Inputs and coerced outputs use the same small, fixed set of Go types the go-ruby-* ecosystem shares (see github.com/go-ruby-dry-types/dry-types), so a host (go-embedded-ruby / rbgo) maps its object graph with no glue:
Ruby Go ---- -- nil nil true / false bool Integer int64, *big.Int Float float64 String string Symbol Symbol Array []any Hash *Map (ordered) Date Date Time / DateTime Time
Rule seam ¶
The custom-`rule` predicate bodies of a dry-validation Contract are the host / rbgo evaluation seam: rbgo runs the Ruby block, and this package exposes the coerced values, a schema-success view, and a RuleContext whose Key/Base .failure methods add errors. The schema and its built-in macro/predicate evaluation are the deterministic core here.
Index ¶
- type Builder
- type Contract
- type Date
- type Key
- func (k *Key) Array(elemType string, elemPreds ...Predicate)
- func (k *Key) ArrayOf(build func(*Builder))
- func (k *Key) Filled(typeName string, preds ...Predicate)
- func (k *Key) Hash(build func(*Builder))
- func (k *Key) Maybe(typeName string, preds ...Predicate)
- func (k *Key) Schema(build func(*Builder))
- func (k *Key) Value(typeName string, preds ...Predicate)
- type Map
- type Message
- type Pair
- type Predicate
- type Result
- type RuleContext
- type Schema
- type Symbol
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder is the DSL receiver inside a Params/JSON block: it collects key rules via Builder.Required and Builder.Optional.
type Contract ¶
type Contract struct {
// contains filtered or unexported fields
}
Contract is a dry-validation contract: a Schema (built with `params`/`json`) plus a list of custom rules that run after the schema against the coerced values. Build one with NewContract, attach the schema, add rules with Contract.Rule/Contract.RuleBase, then apply it with Contract.Call.
The rule bodies are the host / rbgo evaluation seam: the schema and its macro/ predicate evaluation are deterministic Go here, while each rule's predicate logic is a Go closure (in the host, the compiled Ruby block) that inspects the coerced values through a RuleContext and calls Failure to add an error.
func NewContract ¶
NewContract creates a contract wrapping the given schema (built with Params or JSON).
func (*Contract) Call ¶
Call applies the contract: it runs the schema, then every rule whose dependency keys all passed the schema, collecting rule failures into the same errors tree. It returns the combined Result.
func (*Contract) Rule ¶
func (c *Contract) Rule(body func(*RuleContext), keys ...Symbol)
Rule registers a rule keyed on one or more top-level keys. The body runs only if every named key passed the schema; a [RuleContext.Key] failure attaches to the last named key (matching the gem, where `rule(:a, :b)` reports under :a's error path is actually the first — see below). dry-validation reports a keyed `key.failure` under the rule's first key.
func (*Contract) RuleBase ¶
func (c *Contract) RuleBase(body func(*RuleContext))
RuleBase registers a base rule (no dependency keys) whose failures attach to the base (nil) path — dry-validation's `rule do base.failure(...) end`. It runs unconditionally after the schema.
type Date ¶
Date is a Ruby Date, re-exported from dry-types (the coercion target of :date-typed keys).
type Key ¶
type Key struct {
// contains filtered or unexported fields
}
Key is the value-macro attachment point returned by Builder.Required / Builder.Optional. Call exactly one macro method on it (Filled, Maybe, Value, Array, Hash, Schema) to define how the key's value is coerced and validated.
func (*Key) Array ¶
Array coerces the value to an array and coerces+validates each element as elemType with elemPreds (`array(:elem, pred?: arg)`). For an array of hashes, follow with [Key.Each] on the returned member builder; use Key.ArrayOf for the block form.
func (*Key) ArrayOf ¶
ArrayOf coerces the value to an array and validates each element against a nested member schema built by build — dry-schema's `array(:hash) do ... end`. The elements are coerced to hashes and each run through the member schema.
func (*Key) Filled ¶
Filled requires the value to be present and non-empty, coerced to typeName (a dry-types type name like "string"/"integer", or "" for any), then satisfy the predicates. It is dry-schema's `filled(:type, pred?: arg)`.
func (*Key) Hash ¶
Hash coerces the value to a hash and applies a nested schema built by build — dry-schema's `hash do ... end`. A non-hash value reports "must be a hash".
func (*Key) Maybe ¶
Maybe permits nil (nil passes through unchanged); a non-nil value is coerced to typeName and checked against the predicates. It is `maybe(:type, ...)`.
type Map ¶
Map is the insertion-ordered Ruby Hash re-exported from dry-types; schema coercion yields a *Map so key order round-trips.
type Message ¶
type Message struct {
// Text is the failure message, byte-identical to the gem's en locale
// (e.g. "is missing", "must be filled", "must be greater than 18").
Text string
// Path is the key/index path to the value (Symbol or int elements). A base
// error carries the single-element path []any{nil}.
Path []any
}
Message is one validation failure: the message text and the path of keys from the root of the input to the offending value. A path element is a Symbol for a hash key or an int for an array index; the empty path (a base error) is reported by the gem under the nil key.
type Predicate ¶
Predicate is one dry-logic value constraint attached to a schema key (`gt?: 18`, `format?: /.../`, `size?: 3`, …). Name is the predicate without the trailing `?`; Arg is its argument (nil for the arity-1 predicates).
type Result ¶
type Result struct {
// contains filtered or unexported fields
}
Result is the outcome of applying a Schema or a Contract: the coerced output hash plus the errors tree. It mirrors Dry::Schema::Result / Dry::Validation::Result (`.to_h`, `.errors`, `.success?`).
func (*Result) Errors ¶
Errors returns the nested errors hash the way Dry::Schema's `result.errors.to_h` renders it: a *Map whose leaves are []any of message strings, hash keys are Symbol, and array-element keys are int. An empty result yields an empty *Map.
func (*Result) Messages ¶
Messages returns the flat list of every failure with its full key path, in the order dry-validation's `result.errors.each` yields them.
type RuleContext ¶
type RuleContext struct {
// contains filtered or unexported fields
}
RuleContext is the seam a rule body operates through. It exposes the coerced values and records failures. In the host, rbgo runs the Ruby block and drives this context: reading Values and calling Key/Base .failure.
func (*RuleContext) BaseFailure ¶
func (rc *RuleContext) BaseFailure(text string)
BaseFailure adds a base failure under the nil path (dry-validation's `base.failure(text)`).
func (*RuleContext) KeyFailure ¶
func (rc *RuleContext) KeyFailure(text string)
KeyFailure adds a failure at the rule's default key path (dry-validation's `key.failure(text)`). For a base rule (no key) it falls back to the base path.
func (*RuleContext) KeyFailureAt ¶
func (rc *RuleContext) KeyFailureAt(path []any, text string)
KeyFailureAt adds a failure at an explicit key path (dry-validation's `key([:a, :b]).failure(text)`), so a rule can report under a nested or different key than its dependency.
func (*RuleContext) Value ¶
func (rc *RuleContext) Value(key Symbol) (any, bool)
Value returns the coerced value at a top-level key and whether it was present.
func (*RuleContext) Values ¶
func (rc *RuleContext) Values() *Map
Values returns the coerced output hash the rule inspects (dry-validation's `values`). Reading a key: use RuleContext.Value.
type Schema ¶
type Schema struct {
// contains filtered or unexported fields
}
Schema is a dry-schema definition: an ordered list of key rules that, applied to an input hash, coerces the values and produces a Result with the coerced output and a nested errors hash. Build one with Params or JSON and the Key DSL, then apply it with Schema.Call.
func Params ¶
Params starts a Params-namespace schema (form-string coercion — the default dry-validation `params do` block). Call build to add keys, then finish.
func (*Schema) Call ¶
Call applies the schema to input (any hash-shaped value: *Map, map[string]any, map[Symbol]any). It returns a Result carrying the coerced output *Map and the errors tree. A non-hash input yields an empty output and no per-key errors — the caller (a nested hash macro) reports the "must be a hash" type error.
