Expand description
The Seam validation engine. Every binding is a translation layer over this crate and contains no validation logic of its own. If a binding starts growing rules, that is a leak here, to be fixed here.
use seam_core::{parser::parse, validate::validate, value::Value, Limits};
use std::collections::BTreeMap;
let schema = parse("schema Signup { when: DateTime }")?;
let mut payload = BTreeMap::new();
payload.insert("when".to_string(), Value::String("2026-08-29T14:30:00".into()));
let err = validate(&schema, "Signup", &Value::Object(payload), Limits::DEFAULT)
.unwrap_err();
assert_eq!(err.issues[0].code.as_str(), "missing_timezone");Re-exports§
pub use error::Code;pub use error::Issue;pub use error::Path;pub use error::Segment;pub use error::ValidationError;pub use format::Format;pub use limits::Limits;pub use parser::parse;pub use schema::Field;pub use schema::IntType;pub use schema::IntWidth;pub use schema::ObjectType;pub use schema::Presence;pub use schema::Rule;pub use schema::Schema;pub use schema::Type;pub use validate::validate;pub use value::Int;pub use value::Slot;pub use value::Value;
Modules§
- datetime
- Written here rather than delegated to a date crate because the two rules
that matter are policy, not parsing: a
Dateis never widened into an instant, and aDateTimewithout an offset is an error rather than a guess about local time. Typed conversion happens in the bindings. - error
pathandcodeare public API in every binding.codeis stable and changes only on a major version;messageis for humans, never parse it.- format
- Named string formats, checked by hand.
- input
- What the validator needs from a payload, and nothing more.
- json
- JSON read in place.
- limits
- Bounds on hostile input, enforced in the core so every binding inherits them instead of each deriving its own defaults.
- parser
- The
.seamfront end. - schema
- validate
- One walk over the payload, reading it in place.
- value