Skip to main content

Crate tanzim_validate

Crate tanzim_validate 

Source
Expand description

§tanzim-validate

Package | Documentation | Repository

Validate and coerce tanzim-value configuration trees against a schema built from composable validators.

Validators do two jobs:

  • Check that a value has the expected shape (type, range, length, required keys, …).
  • Coerce values in place where the source format lost type information — e.g. a TOML/env string "8080" becomes an integer, an integral float 3.0 becomes 3, and an empty map becomes an empty list.

Because coercion edits the value, the Validator trait works on &mut Value. Validate a whole tanzim_value::LocatedValue node with the free validate function, which also seeds the root location into any error.

Nested validators are passed by value — any Validator converts into the boxed form, so there is no Some(Box::new(...)) ceremony. Use the _any method variants when a key just has to be present without validating its value.

use tanzim_validate::{validate, Integer, StaticMap, Str, Validator};
use tanzim_value::{LocatedValue, Location, Map, Value};

let schema = StaticMap::new()
    .required("host", Str::new().min_chars(1))
    .optional("port", Integer::new().range(1, 65535));

let loc = Location::at("file", "config.toml", None, None, None);
let mut map = Map::new();
map.insert("host".into(), LocatedValue::new(Value::String("localhost".into()), loc.clone()));
map.insert("port".into(), LocatedValue::new(Value::String("8080".into()), loc.clone()));
let mut root = LocatedValue::new(Value::Map(map), loc);

validate(&schema, &mut root).unwrap();
// "8080" was coerced to the integer 8080
assert_eq!(root.value().as_map().unwrap().get("port").unwrap().value().as_int(), Some(8080));

§Validators

Std-only validators (no extra dependencies). Each has its own Cargo feature and all of them are enabled by default; disable default features to trim the set.

  • Primitives: Bool, Integer, Float, Number, Str, List, StaticMap, DynamicMap (boolean, integer, float, number, string, list, static_map, dynamic_map).
  • Choice & constraints: Enum (enumeration), NonEmpty (non_empty), Percentage (percentage).
  • Combinator: Either (either) — accepts the value if either of two validators accepts it.
  • Network: Host, Domain, Email, Port, IpAddr, SocketAddr (net).
  • Filesystem: Path (path), with opt-in filesystem checks.

float/integer imply number; net implies integer.

Number accepts an integer or a float without converting between them. Sign constraints live as builder methods on Integer, Float, and Number: .positive(), .non_negative(), .negative(), .non_positive().

Behind Cargo features (each pulls one external crate):

featurevalidators
regexStr::regex(...), RegexPattern
urlUrl
cidrCidr
uuidUuid
semverSemver
encodingBase64, Hex
durationDuration
bytesizeByteSize
datetimeDateTime, Date

default is the std-only validator set. full enables every validator plus schema (but not logging/tracing).

§Building validators from a schema (schema feature)

With the off-by-default schema feature you can reconstruct a validator from a data document instead of Rust code. A schema node is a map with a "type" tag plus that validator’s options (snake_case, matching the builder methods):

{
  "type": "static_map",
  "fields": {
    "host": { "required": true,  "validator": { "type": "host" } },
    "port": { "required": false, "validator": { "type": "port", "privileged_ok": false } },
    "tags": { "required": false, "validator": {
        "type": "list", "unique": true, "items": { "type": "string", "min_chars": 1 } } },
    "mode": { "required": true, "validator": {
        "type": "either",
        "first":  { "type": "enum", "values": ["auto", "manual"] },
        "second": { "type": "integer", "min": 0 } } }
  }
}

The feature adds only serde as a dependency. Deserialize the document into a SchemaValue with any serde data format (serde_json, etc.), then build:

use tanzim_validate::{build_value, SchemaValue};

let doc: SchemaValue = serde_json::from_str(r#"{"type":"integer","min":1,"max":65535}"#).unwrap();
let validator = build_value(doc.value()).unwrap();

Because the builder works on a tanzim_value::Value, the same path also accepts a tree produced by tanzim-parse directly (no serde call needed) — which is how the tanzim facade will wire it in.

Dispatch goes through a Registry; Registry::with_builtins() knows every built-in tag (feature-gated ones included when their feature is on), and Registry::register adds custom validator types. Schema-construction problems surface as a SchemaError carrying a field path and, when built from a located tree, a source location.

Structs§

Base64
(encoding feature) Accepts a standard (RFC 4648) base64-encoded string.
Bool
(boolean feature) Accepts only a boolean value. No coercion, no options.
ByteSize
(bytesize feature) Accepts a human byte-size string (e.g. "10MB", "1GiB") and coerces it to an integer number of bytes.
Cidr
(cidr feature) Accepts a CIDR network such as 10.0.0.0/8 or 2001:db8::/32.
Date
(datetime feature) Accepts a calendar date such as 2024-01-02.
DateTime
(datetime feature) Accepts an RFC 3339 timestamp such as 2024-01-02T15:04:05Z.
Domain
(net feature) Accepts a DNS domain name, normalizing it to lowercase.
Duration
(duration feature) Accepts a human duration string (e.g. "30s", "5m", "1h30m") and coerces it to an integer number of seconds (or milliseconds with Duration::millis).
DynamicMap
(dynamic_map feature) Accepts a map with arbitrary keys and uniform values.
Either
(either feature) Accepts the value if either of two validators accepts it.
Email
(net feature) Accepts an email address, normalizing the domain part to lowercase.
Enum
(enumeration feature) Accepts a value drawn from a fixed allow-list. The allowed values may be of any type, and are compared by equality (no coercion).
Error
A validation failure, carrying a breadcrumb path and (when known) the source Location of the offending value.
Float
(float feature) Accepts a float, with optional inclusive bounds and lenient coercion.
Hex
(encoding feature) Accepts a hexadecimal string (even number of 0-9a-fA-F digits).
Host
(net feature) Accepts a hostname or an IP address literal.
Integer
(integer feature) Accepts an integer, with optional inclusive bounds and lenient coercion.
IpAddr
(net feature) Accepts an IP address literal.
List
(list feature) Accepts a list, with optional length bounds, a uniqueness check, and an optional per-item validator.
LocatedValue
A Value with its Location and an optional Comment.
Location
Source and optional position of a configuration value.
Map
Ordered map of configuration keys to located values (last key wins on lookup).
Meta
Human-facing metadata a validator carries and attaches to its errors.
Node
A validator node: the map of options plus what’s needed to read them and recurse.
NonEmpty
(non_empty feature) Accepts a non-blank string (at least one non-whitespace character).
Number
(number feature) Accepts either an integer or a float, without converting between them.
Path
(path feature) Accepts a filesystem path string.
Percentage
(percentage feature) Accepts a percentage: an integer in 0..=100, or a float ratio in 0.0..=1.0.
Port
(net feature) Accepts a TCP/UDP port number, coercing numeric strings and floats like crate::Integer.
RegexPattern
(regex feature) Accepts a string that is itself a valid regular expression.
Registry
Maps "type" tags to validator constructors.
SchemaError
A schema-construction failure, with a breadcrumb path and (when known) source location.
SchemaValue
A Value that can be produced by any serde deserializer (e.g. serde_json).
Semver
(semver feature) Accepts a semantic version string such as 1.4.2 or 2.0.0-rc.1.
SocketAddr
(net feature) Accepts a host:port socket address (IP or hostname host).
StaticMap
(static_map feature) Accepts a map with a known set of keys.
Str
(string feature) Accepts a string, with optional length bounds and (with the regex feature) a pattern. No coercion: non-string values are rejected.
Url
(url feature) Accepts a URL, optionally restricting the scheme and requiring a host.
Uuid
(uuid feature) Accepts a UUID string in the canonical hyphenated form.

Enums§

ErrorKind
What went wrong while validating a value.
PathKind
(path feature) The kind of filesystem entry a Path must point at.
SchemaErrorKind
What went wrong while building a validator from a schema document.
Segment
One step in the path from the validated root to the offending value.
Value
Dynamically typed configuration value.
ValueType
Kind of value stored in Value.

Traits§

Validator
A validator: a rule (check) plus human-facing Meta.
WithMeta
Getters and fluent setters for every validator’s Meta.

Functions§

build
Build a validator from a located schema node using a default Registry.
build_value
Build a validator from a bare Value using a default Registry.
validate
Validate a whole node, seeding the root Location into any error.

Type Aliases§

Constructor
Constructs one validator kind from its Node.