pub struct ObjectSchema { /* private fields */ }Expand description
A schema for validating JSON objects.
ObjectSchema validates that values are objects and optionally applies
constraints like required fields, optional fields with defaults, and
additional property handling. All field validation errors are accumulated
rather than short-circuiting on the first failure.
§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())
.additional_properties(false);
let result = schema.validate(&json!({
"name": "Alice",
"age": 30
}), &JsonPath::root());
assert!(result.is_success());Implementations§
Source§impl ObjectSchema
impl ObjectSchema
Sourcepub fn field<S>(self, name: impl Into<String>, schema: S) -> Selfwhere
S: SchemaLike + 'static,
pub fn field<S>(self, name: impl Into<String>, schema: S) -> Selfwhere
S: SchemaLike + 'static,
Adds a required field to the schema.
The field must be present in the input object and its value must pass validation against the provided schema.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::object()
.field("name", Schema::string().min_len(1));
// Missing required field produces error
let result = schema.validate(&json!({}), &JsonPath::root());
assert!(result.is_failure());Sourcepub fn optional<S>(self, name: impl Into<String>, schema: S) -> Selfwhere
S: SchemaLike + 'static,
pub fn optional<S>(self, name: impl Into<String>, schema: S) -> Selfwhere
S: SchemaLike + 'static,
Adds an optional field to the schema.
The field may be absent from the input object. If present, its value must pass validation against the provided schema.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::object()
.optional("nickname", Schema::string());
// Missing optional field is OK
let result = schema.validate(&json!({}), &JsonPath::root());
assert!(result.is_success());Sourcepub fn default<S>(
self,
name: impl Into<String>,
schema: S,
default: Value,
) -> Selfwhere
S: SchemaLike + 'static,
pub fn default<S>(
self,
name: impl Into<String>,
schema: S,
default: Value,
) -> Selfwhere
S: SchemaLike + 'static,
Adds an optional field with a default value.
If the field is absent from the input object, the default value is used. If present, its value must pass validation against the provided schema.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::object()
.default("role", Schema::string(), json!("user"));
let result = schema.validate(&json!({}), &JsonPath::root());
assert!(result.is_success());
// The validated object will include "role": "user"Sourcepub fn additional_properties<S>(self, setting: S) -> Selfwhere
S: Into<AdditionalPropertiesSetting>,
pub fn additional_properties<S>(self, setting: S) -> Selfwhere
S: Into<AdditionalPropertiesSetting>,
Configures how unknown properties are handled.
By default, unknown properties are allowed. Use this method to reject unknown properties or validate them against a schema.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
// Reject unknown properties
let strict = Schema::object()
.field("name", Schema::string())
.additional_properties(false);
let result = strict.validate(&json!({
"name": "Alice",
"unknown": "field"
}), &JsonPath::root());
assert!(result.is_failure());
// Validate unknown properties against a schema
let validated = Schema::object()
.field("name", Schema::string())
.additional_properties(Schema::string());Sourcepub fn error(self, message: impl Into<String>) -> Self
pub fn error(self, message: impl Into<String>) -> Self
Sets a custom error message for type errors.
This message is used when the input value is not an object.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
let schema = Schema::object()
.error("must be a user object");
let result = schema.validate(&json!("not an object"), &JsonPath::root());
// Error message will be "must be a user object"Sourcepub fn custom<F>(self, validator: F) -> Self
pub fn custom<F>(self, validator: F) -> Self
Adds a custom cross-field validator.
Cross-field validators run after all field-level validations pass (or fail,
depending on skip_on_field_errors configuration). They receive a
ValidatedObject containing all validated field values.
§Example
use postmortem::{Schema, JsonPath};
use serde_json::json;
use stillwater::Validation;
let schema = Schema::object()
.field("quantity", Schema::integer().positive())
.field("unit_price", Schema::integer().non_negative())
.field("total", Schema::integer().non_negative())
.custom(|obj, path| {
let qty = obj.get("quantity").and_then(|v| v.as_i64()).unwrap_or(0);
let price = obj.get("unit_price").and_then(|v| v.as_i64()).unwrap_or(0);
let total = obj.get("total").and_then(|v| v.as_i64()).unwrap_or(0);
if qty * price != total {
Validation::Failure(postmortem::SchemaErrors::single(
postmortem::SchemaError::new(
path.push_field("total"),
"total must equal quantity * unit_price"
).with_code("invalid_total")
))
} else {
Validation::Success(())
}
});Sourcepub fn skip_cross_field_on_errors(self, skip: bool) -> Self
pub fn skip_cross_field_on_errors(self, skip: bool) -> Self
Configure whether to skip cross-field validation if field validation fails.
Default: true (skip cross-field when fields are invalid).
When true, cross-field validators only run if all field-level validations
pass. This is usually the desired behavior since cross-field validators
often assume fields have valid values.
Set to false to always run cross-field validators, even if some field
validations failed.
§Example
use postmortem::Schema;
let schema = Schema::object()
.field("name", Schema::string())
.skip_cross_field_on_errors(false); // Always run cross-field validatorsSourcepub fn require_if<P>(
self,
condition_field: impl Into<String>,
predicate: P,
required_field: impl Into<String>,
) -> Self
pub fn require_if<P>( self, condition_field: impl Into<String>, predicate: P, required_field: impl Into<String>, ) -> Self
Requires a field when a condition is met.
If the condition field matches the predicate, the required field must be present.
§Example
use postmortem::Schema;
use serde_json::json;
let schema = Schema::object()
.field("method", Schema::string())
.optional("card_number", Schema::string())
.require_if("method", |v| v == &json!("card"), "card_number");Sourcepub fn mutually_exclusive(
self,
field1: impl Into<String>,
field2: impl Into<String>,
) -> Self
pub fn mutually_exclusive( self, field1: impl Into<String>, field2: impl Into<String>, ) -> Self
Ensures two fields are mutually exclusive.
At most one of the two fields can be present (non-null).
§Example
use postmortem::Schema;
let schema = Schema::object()
.optional("email", Schema::string())
.optional("phone", Schema::string())
.mutually_exclusive("email", "phone");Sourcepub fn at_least_one_of<I, S>(self, fields: I) -> Self
pub fn at_least_one_of<I, S>(self, fields: I) -> Self
Requires at least one of the specified fields to be present.
At least one field must exist and be non-null.
§Example
use postmortem::Schema;
let schema = Schema::object()
.optional("email", Schema::string())
.optional("phone", Schema::string())
.at_least_one_of(["email", "phone"]);Sourcepub fn equal_fields(
self,
field1: impl Into<String>,
field2: impl Into<String>,
) -> Self
pub fn equal_fields( self, field1: impl Into<String>, field2: impl Into<String>, ) -> Self
Ensures two fields have equal values.
If both fields are present, their values must be equal.
§Example
use postmortem::Schema;
let schema = Schema::object()
.field("password", Schema::string())
.field("confirm_password", Schema::string())
.equal_fields("password", "confirm_password");Sourcepub fn field_less_than(
self,
field1: impl Into<String>,
field2: impl Into<String>,
) -> Self
pub fn field_less_than( self, field1: impl Into<String>, field2: impl Into<String>, ) -> Self
Ensures field1 is less than field2.
Works for numbers and strings (lexicographic comparison). Skips validation if fields are missing, null, or have incompatible types.
§Example
use postmortem::Schema;
let schema = Schema::object()
.field("start_date", Schema::string())
.field("end_date", Schema::string())
.field_less_than("start_date", "end_date");Sourcepub fn field_less_or_equal(
self,
field1: impl Into<String>,
field2: impl Into<String>,
) -> Self
pub fn field_less_or_equal( self, field1: impl Into<String>, field2: impl Into<String>, ) -> Self
Ensures field1 is less than or equal to field2.
Works for numbers and strings (lexicographic comparison). Skips validation if fields are missing, null, or have incompatible types.
§Example
use postmortem::Schema;
let schema = Schema::object()
.field("min", Schema::integer())
.field("max", Schema::integer())
.field_less_or_equal("min", "max");Sourcepub fn validate(
&self,
value: &Value,
path: &JsonPath,
) -> Validation<Map<String, Value>, SchemaErrors>
pub fn validate( &self, value: &Value, path: &JsonPath, ) -> Validation<Map<String, Value>, SchemaErrors>
Validates a value against this schema.
Returns Validation::Success with a Map<String, Value> containing
the validated fields if all validations pass, or Validation::Failure
with accumulated errors if any validations fail.
Trait Implementations§
Source§impl Default for ObjectSchema
impl Default for ObjectSchema
Source§impl SchemaLike for ObjectSchema
impl SchemaLike for ObjectSchema
Source§fn validate(
&self,
value: &Value,
path: &JsonPath,
) -> Validation<Self::Output, SchemaErrors>
fn validate( &self, value: &Value, path: &JsonPath, ) -> Validation<Self::Output, SchemaErrors>
Source§fn validate_to_value(
&self,
value: &Value,
path: &JsonPath,
) -> Validation<Value, SchemaErrors>
fn validate_to_value( &self, value: &Value, path: &JsonPath, ) -> Validation<Value, SchemaErrors>
serde_json::Value. Read moreSource§fn validate_with_context(
&self,
value: &Value,
path: &JsonPath,
context: &ValidationContext,
) -> Validation<Self::Output, SchemaErrors>
fn validate_with_context( &self, value: &Value, path: &JsonPath, context: &ValidationContext, ) -> Validation<Self::Output, SchemaErrors>
Source§fn validate_to_value_with_context(
&self,
value: &Value,
path: &JsonPath,
context: &ValidationContext,
) -> Validation<Value, SchemaErrors>
fn validate_to_value_with_context( &self, value: &Value, path: &JsonPath, context: &ValidationContext, ) -> Validation<Value, SchemaErrors>
serde_json::Value. Read moreAuto Trait Implementations§
impl Freeze for ObjectSchema
impl !RefUnwindSafe for ObjectSchema
impl Send for ObjectSchema
impl Sync for ObjectSchema
impl Unpin for ObjectSchema
impl !UnwindSafe for ObjectSchema
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<S> ValueValidator for Swhere
S: SchemaLike,
impl<S> ValueValidator for Swhere
S: SchemaLike,
Source§fn validate_value(
&self,
value: &Value,
path: &JsonPath,
) -> Validation<Value, SchemaErrors>
fn validate_value( &self, value: &Value, path: &JsonPath, ) -> Validation<Value, SchemaErrors>
serde_json::Value.Source§fn validate_value_with_context(
&self,
value: &Value,
path: &JsonPath,
context: &ValidationContext,
) -> Validation<Value, SchemaErrors>
fn validate_value_with_context( &self, value: &Value, path: &JsonPath, context: &ValidationContext, ) -> Validation<Value, SchemaErrors>
serde_json::Value. Read more