Repository navigation
One `Validate` to rule them all
This release unifies dv8's API around a single name and makes the directive language explicit and strict. The dv8.ValidateContext entry point is removed: dv8.Validate now takes a context.Context as its first argument, with nil tolerated and treated as context.Background. The ValidatorContext interface is gone as well: Validator itself is now the context-taking interface, Validate(ctx context.Context) error, reaching any type in the object graph that implements it, while a parameterless Validate() error is honored as a fallback for types not written for dv8. Since Go forbids two same-named methods, the compiler enforces that a type implements at most one variant. The directive language is reworked for explicitness: directives on an array or map now apply to the container itself, the new each prefix distributes a directive to elements or map values, and the new key prefix applies directives to map keys, with mutated keys reinserted under their new value and two keys folding into one reported as an error. Consequently arrlen and maplen are retired in favor of plain len, and a nil container now has length 0, making notzero the nil check. required is renamed to notzero to say what it actually checks, main is renamed to delegate, and whitespace trimming is no longer applied by default, with notrim replaced by an opt-in trim. A comma inside a directive's value, such as a regexp quantifier, is now escaped with a backslash, written \\, in the tag, mirroring invopop/jsonschema. Directives are also strictly compiled once per type on first use: typos, misapplied directives, malformed operators or values, uncompilable regexps, and on targets that do not exist all fail with an error wrapping the new dv8.ErrDirective, which errors.Is distinguishes from invalid data, and the new dv8.Compile surfaces broken directives eagerly at startup before any data arrives. Compiled regular expressions are now cached, and a bug was fixed where a pointer-receiver context validator was silently skipped when the type did not also implement the parameterless variant. Upgrading from v0.2.x: pass a context (or nil) as the first argument of dv8.Validate, rename ValidateContext(ctx) methods to Validate(ctx), replace arrlen/maplen with len, prefix per-item directives with each, rename required to notzero and main to delegate, and add trim where trimming is desired. Note two silent behavior changes the strict compiler cannot catch: string fields that relied on implicit trimming, including required checks that counted on all-whitespace values being rejected, and container fields whose per-item rules now need an each prefix.