pub struct Rule<T: ?Sized> { /* private fields */ }Expand description
A composable validation rule for values of type T.
Rules are the building blocks of domainstack’s validation system. They can be composed
using and(), or(), not(), and when() to create complex validation logic.
Rules now receive a RuleContext providing field information for better error messages.
§Examples
§Basic Rule
use domainstack::prelude::*;
let rule = rules::min_len(3);
let ctx = RuleContext::root("username");
assert!(rule.apply_with_context("alice", &ctx).is_empty());
assert!(!rule.apply_with_context("ab", &ctx).is_empty());§Composing Rules
use domainstack::prelude::*;
// Username must be 3-20 characters and alphanumeric
let rule = rules::min_len(3)
.and(rules::max_len(20))
.and(rules::alphanumeric());
let ctx = RuleContext::root("username");
assert!(rule.apply_with_context("alice123", &ctx).is_empty());
assert!(!rule.apply_with_context("ab", &ctx).is_empty()); // too short§Custom Rules with Context
use domainstack::{Rule, RuleContext, ValidationError, Path};
fn lowercase_only() -> Rule<str> {
Rule::new(|value: &str, ctx: &RuleContext| {
if value.chars().all(|c| c.is_lowercase() || !c.is_alphabetic()) {
ValidationError::default()
} else {
ValidationError::single(
ctx.full_path(),
"not_lowercase",
"Must contain only lowercase letters"
)
}
})
}
let rule = lowercase_only();
let ctx = RuleContext::root("username");
assert!(rule.apply_with_context("hello", &ctx).is_empty());
assert!(!rule.apply_with_context("Hello", &ctx).is_empty());Implementations§
Source§impl<T: ?Sized + 'static> Rule<T>
impl<T: ?Sized + 'static> Rule<T>
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new validation rule.
Rules receive both the value to validate and a RuleContext providing
field information for better error messages.
Sourcepub fn apply(&self, value: &T) -> ValidationError
pub fn apply(&self, value: &T) -> ValidationError
Applies the rule with an anonymous context.
For better error messages, use apply_with_context() instead.
Sourcepub fn apply_with_context(
&self,
value: &T,
ctx: &RuleContext,
) -> ValidationError
pub fn apply_with_context( &self, value: &T, ctx: &RuleContext, ) -> ValidationError
Applies the rule with a specific context for field-aware error messages.
Sourcepub fn code(self, code: &'static str) -> Rule<T>
pub fn code(self, code: &'static str) -> Rule<T>
Customize the error code for validation failures.
§Examples
use domainstack::prelude::*;
let rule = rules::min_len(5).code("email_too_short");
let err = rule.apply("hi");
assert_eq!(err.violations[0].code, "email_too_short");Sourcepub fn message(
self,
msg: impl Into<String> + Clone + Send + Sync + 'static,
) -> Rule<T>
pub fn message( self, msg: impl Into<String> + Clone + Send + Sync + 'static, ) -> Rule<T>
Customize the error message for validation failures.
§Examples
use domainstack::prelude::*;
let rule = rules::min_len(5).message("Email too short");
let err = rule.apply("hi");
assert_eq!(err.violations[0].message, "Email too short");Sourcepub fn meta(
self,
key: &'static str,
value: impl Into<String> + Clone + Send + Sync + 'static,
) -> Rule<T>
pub fn meta( self, key: &'static str, value: impl Into<String> + Clone + Send + Sync + 'static, ) -> Rule<T>
Add metadata to validation errors.
§Examples
use domainstack::prelude::*;
let rule = rules::min_len(5)
.meta("hint", "Use at least 5 characters");
let err = rule.apply("hi");
assert_eq!(err.violations[0].meta.get("hint"), Some("Use at least 5 characters"));pub fn and(self, other: Rule<T>) -> Rule<T>
pub fn or(self, other: Rule<T>) -> Rule<T>
pub fn not(self, code: &'static str, message: &'static str) -> Rule<T>
pub fn map_path( self, prefix: impl Into<Path> + Clone + Send + Sync + 'static, ) -> Rule<T>
pub fn when<F>(self, predicate: F) -> Rule<T>
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for Rule<T>where
T: ?Sized,
impl<T> !RefUnwindSafe for Rule<T>
impl<T> Send for Rule<T>where
T: ?Sized,
impl<T> Sync for Rule<T>where
T: ?Sized,
impl<T> Unpin for Rule<T>where
T: ?Sized,
impl<T> !UnwindSafe for Rule<T>
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
Mutably borrows from an owned value. Read more