Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4c4562c
feat(validation): add Rule::Date and Rule::DateRange with chrono/jiff…
elycruz Feb 23, 2026
abe8ea3
feat(validation): promote Rule::Email to Email(EmailOptions)
elycruz Feb 23, 2026
dc676f5
Update crates/validation/src/rule_impls/date_jiff.rs
elycruz Feb 23, 2026
7135dc0
Initial plan
Copilot Feb 23, 2026
0e31dbb
Fix date range bound parsing to handle cross-format scenarios (date-o…
Copilot Feb 23, 2026
74a5fee
Merge pull request #96 from elycruz/copilot/sub-pr-94
elycruz Feb 23, 2026
b1d8095
Update crates/validation/src/rule_impls/string.rs
elycruz Feb 23, 2026
414da91
Update crates/validation/src/rule_impls/string.rs
elycruz Feb 23, 2026
82b985e
Initial plan
Copilot Feb 23, 2026
94dcea5
Fix Rule::email() API inconsistency: require EmailOptions parameter
Copilot Feb 23, 2026
1c95319
Merge pull request #97 from elycruz/copilot/sub-pr-95
elycruz Feb 23, 2026
47e9867
Merge pull request #95 from elycruz/feat/email-options
elycruz Feb 23, 2026
358773f
Initial plan
Copilot Feb 23, 2026
82f0b25
Initial plan
Copilot Feb 23, 2026
f3f5e9c
Update crates/validation/src/options.rs
elycruz Feb 23, 2026
0045785
Replace format! macro calls with const datetime format strings in dat…
Copilot Feb 23, 2026
090eb18
Replace format! macro calls with const datetime format strings in dat…
Copilot Feb 23, 2026
b8b75e2
Merge pull request #98 from elycruz/copilot/sub-pr-94
elycruz Feb 23, 2026
00d88aa
Merge pull request #99 from elycruz/copilot/sub-pr-94-again
elycruz Feb 23, 2026
a36e5a3
Update crates/validation/src/rule_impls/date_jiff.rs
elycruz Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/form/examples/localized_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl LocalizedFormValidator {
_ => "Email is required".to_string(),
}, None)
.and(
Rule::<String>::Email.with_message_provider(|ctx| match ctx.locale {
Rule::<String>::Email(Default::default()).with_message_provider(|ctx| match ctx.locale {
Some("es") => "El formato del correo electrónico no es válido".to_string(),
Some("fr") => "Le format de l'adresse e-mail est invalide".to_string(),
Some("de") => "Ungültiges E-Mail-Format".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion crates/inputfilter/examples/field_basics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn main() {
println!("\n3. Field with filters:");
let email_field = FieldBuilder::<String>::default()
.name("email")
.rule(Rule::Required.and(Rule::Email))
.rule(Rule::Required.and(Rule::Email(Default::default())))
.filters(vec![Filter::Trim, Filter::Lowercase])
.build()
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/inputfilter/examples/field_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn main() {
// { "type": "email", "name": "email", "required": true, "minlength": 5, "maxlength": 128 }
// Allows rules to be sent to front-end clients so that they're shared
// instead of isolated.
.rule(All(vec![Required, MinLength(5), MaxLength(128), Email]))
.rule(All(vec![Required, MinLength(5), MaxLength(128), Email(Default::default())]))
.build()
.unwrap(),
)
Expand Down
4 changes: 2 additions & 2 deletions crates/inputfilter/examples/json_serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn main() {
println!("\n2. Serialize a field with filters:");
let email_field = FieldBuilder::<String>::default()
.name("email")
.rule(Rule::Required.and(Rule::Email))
.rule(Rule::Required.and(Rule::Email(Default::default())))
.filters(vec![Filter::Trim, Filter::Lowercase])
.build()
.unwrap();
Expand Down Expand Up @@ -69,7 +69,7 @@ fn main() {

// Example 5: Serialize Rule::Any
println!("\n5. Serialize Rule::Any:");
let any_rule = Rule::<String>::Any(vec![Rule::Email, Rule::Pattern(r"^\d{10}$".to_string())]);
let any_rule = Rule::<String>::Any(vec![Rule::Email(Default::default()), Rule::Pattern(r"^\d{10}$".to_string())]);

let json = serde_json::to_string_pretty(&any_rule).unwrap();
println!("{}", json);
Expand Down
2 changes: 1 addition & 1 deletion crates/inputfilter/examples/localized_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ fn main() {

let email_rule = Rule::<String>::Required
.with_message_provider(|ctx| translate("email.required", ctx.locale), None)
.and(Rule::<String>::Email.with_message_provider(|ctx| translate("email.invalid", ctx.locale), None));
.and(Rule::<String>::Email(Default::default()).with_message_provider(|ctx| translate("email.invalid", ctx.locale), None));

let invalid_email = "not-an-email".to_string();

Expand Down
6 changes: 3 additions & 3 deletions crates/inputfilter/examples/rule_composition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn main() {

// Example 4: Using .or() combinator (Any must pass)
println!("\n4. Using .or() combinator (Any must pass):");
let contact_rule = Rule::<String>::Email.or(Rule::Pattern(r"^\d{3}-\d{4}$".to_string()));
let contact_rule = Rule::<String>::Email(Default::default()).or(Rule::Pattern(r"^\d{3}-\d{4}$".to_string()));

println!(
" 'user@example.com': {:?}",
Expand All @@ -90,7 +90,7 @@ fn main() {
// Example 5: Using Rule::Any directly
println!("\n5. Using Rule::Any directly:");
let flexible_id = Rule::<String>::Any(vec![
Rule::Email,
Rule::Email(Default::default()),
Rule::Pattern(r"^\d{5,10}$".to_string()), // Numeric ID
Rule::Pattern(r"^[A-Z]{2}\d{6}$".to_string()), // Code format
]);
Expand Down Expand Up @@ -155,7 +155,7 @@ fn main() {

// Example 9: Pattern matching
println!("\n9. Pattern matching:");
let email_pattern = Rule::<String>::Email;
let email_pattern = Rule::<String>::Email(Default::default());
let url_pattern = Rule::<String>::Url(Default::default());
let custom_pattern = Rule::<String>::Pattern(r"^[a-z]+$".to_string());

Expand Down
2 changes: 1 addition & 1 deletion crates/inputfilter/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use walrs_validation::{Rule, ValidateRef, Violations};
/// // Field with rule and filters
/// let field = FieldBuilder::<String>::default()
/// .name("email")
/// .rule(Rule::Required.and(Rule::Email))
/// .rule(Rule::Required.and(Rule::Email(Default::default())))
/// .filters(vec![Filter::Trim, Filter::Lowercase])
/// .build()
/// .unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/inputfilter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
//! let email_field = FieldBuilder::<String>::default()
//! .name("email".to_string())
//! .filters(vec![FilterEnum::Trim, FilterEnum::Lowercase])
//! .rule(Rule::Required.and(Rule::Email))
//! .rule(Rule::Required.and(Rule::Email(Default::default())))
//! .build()
//! .unwrap();
//!
Expand Down
4 changes: 4 additions & 0 deletions crates/validation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ include = ["src/**/*", "Cargo.toml"]
default = ["serde_json_bridge"]
serde_json_bridge = ["dep:serde_json"]
indexmap = ["dep:indexmap"]
chrono = ["dep:chrono"]
jiff = ["dep:jiff"]

[dependencies]
chrono = { version = "0.4", optional = true }
indexmap = { version = "2", features = ["serde"], optional = true }
jiff = { version = "0.2", optional = true }
regex = "1.3.1"
serde = { version = "1.0.103", features = ["derive"] }
serde_json = { version = "1.0.82", optional = true }
Expand Down
Loading
Loading