pub struct Schema;Expand description
Entry point for creating validation schemas.
Schema provides factory methods for creating different schema types.
Each schema type validates specific value types and supports various
constraints through a builder pattern.
§Example
use postmortem::Schema;
// Create a string schema with length constraints
let string_schema = Schema::string()
.min_len(1)
.max_len(100);
// Create a string schema with pattern validation
let email_schema = Schema::string()
.pattern(r"@")
.unwrap()
.error("must contain @");Implementations§
Source§impl Schema
impl Schema
Sourcepub fn string() -> StringSchema
pub fn string() -> StringSchema
Creates a new string schema.
The returned schema validates that values are strings. Use builder methods to add constraints like minimum/maximum length or patterns.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::string().min_len(5);
let result = schema.validate(&json!("hello"), &JsonPath::root());
assert!(result.is_success());
let result = schema.validate(&json!("hi"), &JsonPath::root());
assert!(result.is_failure());Sourcepub fn integer() -> IntegerSchema
pub fn integer() -> IntegerSchema
Creates a new integer schema.
The returned schema validates that values are integers (not floats). Use builder methods to add constraints like minimum/maximum value, range, or sign requirements.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::integer().min(0).max(100);
let result = schema.validate(&json!(50), &JsonPath::root());
assert!(result.is_success());
let result = schema.validate(&json!(-5), &JsonPath::root());
assert!(result.is_failure());
// Float values are rejected
let result = schema.validate(&json!(1.5), &JsonPath::root());
assert!(result.is_failure());Sourcepub fn object() -> ObjectSchema
pub fn object() -> ObjectSchema
Creates a new object schema.
The returned schema validates that values are JSON objects. Use builder methods to define required fields, optional fields, default values, and control handling of additional properties.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::object()
.field("name", Schema::string().min_len(1))
.field("age", Schema::integer().positive())
.optional("email", Schema::string())
.default("role", Schema::string(), json!("user"))
.additional_properties(false);
let result = schema.validate(&json!({
"name": "Alice",
"age": 30
}), &JsonPath::root());
assert!(result.is_success());
// Missing required field produces error
let result = schema.validate(&json!({"name": "Bob"}), &JsonPath::root());
assert!(result.is_failure());Sourcepub fn array<S: SchemaLike>(item_schema: S) -> ArraySchema<S>
pub fn array<S: SchemaLike>(item_schema: S) -> ArraySchema<S>
Creates a new array schema with the given item schema.
The returned schema validates that values are arrays and that each item passes validation against the provided item schema. Use builder methods to add constraints like minimum/maximum length or uniqueness.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
// Array of positive integers
let schema = Schema::array(Schema::integer().positive())
.min_len(1)
.max_len(10);
let result = schema.validate(&json!([1, 2, 3]), &JsonPath::root());
assert!(result.is_success());
// Empty array fails min_len constraint
let result = schema.validate(&json!([]), &JsonPath::root());
assert!(result.is_failure());
// Non-positive integer fails item validation
let result = schema.validate(&json!([1, -2, 3]), &JsonPath::root());
assert!(result.is_failure());Sourcepub fn one_of<I>(schemas: I) -> CombinatorSchema
pub fn one_of<I>(schemas: I) -> CombinatorSchema
Creates a one-of combinator schema.
Exactly one of the provided schemas must match. This is ideal for discriminated unions where a value must be one of several distinct types.
§Example
use postmortem::{Schema, ValueValidator, SchemaLike, JsonPath};
use serde_json::json;
// Shape can be either a circle or rectangle
let shape = Schema::one_of(vec![
Box::new(Schema::object()
.field("type", Schema::string())
.field("radius", Schema::integer().positive())) as Box<dyn ValueValidator>,
Box::new(Schema::object()
.field("type", Schema::string())
.field("width", Schema::integer().positive())
.field("height", Schema::integer().positive())) as Box<dyn ValueValidator>,
]);
let result = shape.validate(&json!({
"type": "circle",
"radius": 5
}), &JsonPath::root());
assert!(result.is_success());Sourcepub fn any_of<I>(schemas: I) -> CombinatorSchema
pub fn any_of<I>(schemas: I) -> CombinatorSchema
Creates an any-of combinator schema.
At least one of the provided schemas must match. This is more permissive
than one_of and allows multiple matches. Validation short-circuits on
the first match.
§Example
use postmortem::{Schema, ValueValidator, SchemaLike, JsonPath};
use serde_json::json;
// ID can be either a string or positive integer
let id = Schema::any_of(vec![
Box::new(Schema::string().min_len(1)) as Box<dyn ValueValidator>,
Box::new(Schema::integer().positive()) as Box<dyn ValueValidator>,
]);
let result = id.validate(&json!("abc-123"), &JsonPath::root());
assert!(result.is_success());
let result = id.validate(&json!(42), &JsonPath::root());
assert!(result.is_success());Sourcepub fn all_of<I>(schemas: I) -> CombinatorSchema
pub fn all_of<I>(schemas: I) -> CombinatorSchema
Creates an all-of combinator schema.
All of the provided schemas must match. This is useful for schema composition and intersection, where a value must satisfy multiple independent constraints.
§Example
use postmortem::{Schema, ValueValidator, SchemaLike, JsonPath};
use serde_json::json;
// Entity must have both a name and a timestamp
let named = Schema::object()
.field("name", Schema::string().min_len(1));
let timestamped = Schema::object()
.field("created_at", Schema::string());
let entity = Schema::all_of(vec![
Box::new(named) as Box<dyn ValueValidator>,
Box::new(timestamped) as Box<dyn ValueValidator>,
]);
let result = entity.validate(&json!({
"name": "Alice",
"created_at": "2025-01-01"
}), &JsonPath::root());
assert!(result.is_success());Sourcepub fn optional(inner: Box<dyn ValueValidator>) -> CombinatorSchema
pub fn optional(inner: Box<dyn ValueValidator>) -> CombinatorSchema
Creates an optional combinator schema.
The value can be null. Non-null values are validated against the inner schema.
§Example
use postmortem::{Schema, ValueValidator, SchemaLike, JsonPath};
use serde_json::json;
let optional_string = Schema::optional(
Box::new(Schema::string().min_len(1)) as Box<dyn ValueValidator>
);
// Null is valid
let result = optional_string.validate(&json!(null), &JsonPath::root());
assert!(result.is_success());
// Non-null values are validated
let result = optional_string.validate(&json!("hello"), &JsonPath::root());
assert!(result.is_success());
let result = optional_string.validate(&json!(""), &JsonPath::root());
assert!(result.is_failure());Sourcepub fn ref_(name: impl Into<String>) -> RefSchema
pub fn ref_(name: impl Into<String>) -> RefSchema
Creates a reference to a named schema.
Schema references enable reuse and recursive structures. The referenced
schema must be registered in a SchemaRegistry before validation.
References can only be validated through a registry. Attempting to validate
without a registry produces an error with code missing_registry.
§Example
use postmortem::{Schema, SchemaRegistry};
use serde_json::json;
let registry = SchemaRegistry::new();
// Register base schema
registry.register("UserId", Schema::integer().positive()).unwrap();
// Use reference in another schema
registry.register("User", Schema::object()
.field("id", Schema::ref_("UserId"))
.field("name", Schema::string())
).unwrap();
let result = registry.validate("User", &json!({
"id": 42,
"name": "Alice"
})).unwrap();
assert!(result.is_success());