Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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.

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
50 changes: 50 additions & 0 deletions crates/validation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ The `Rule` enum provides built-in validation for common constraints:
- `Rule::Email` - Email format validation
- `Rule::Step` - Step/multiple validation
- `Rule::Hostname` - Configurable hostname validation (DNS/IP/local/public IPv4)
- `Rule::Date` - Date format validation (ISO 8601, US, EU, RFC 2822, custom)
- `Rule::DateRange` - Date range validation with min/max bounds
- `Rule::Custom` - Custom closure-based validation

## Rule Composition
Expand Down Expand Up @@ -89,6 +91,54 @@ The `serde_json_bridge` feature (enabled by default) provides `From<serde_json::

The `indexmap` feature provides `From<IndexMap<String, V>> for Value` for constructing `Value::Object` from an `IndexMap`.

### Date Validation (`chrono` / `jiff`)

Date validation requires enabling one of the date crate features:

```toml
# Using chrono (most popular, widest ecosystem)
walrs_validation = { path = "../validation", features = ["chrono"] }

# Using jiff (modern API, best timezone handling)
walrs_validation = { path = "../validation", features = ["jiff"] }
```

**String-based validation** — validate date strings with `Rule::Date` and `Rule::DateRange`:

```rust,ignore
use walrs_validation::{Rule, DateOptions, DateRangeOptions, DateFormat};

// Validate ISO 8601 date strings
let rule = Rule::<String>::Date(DateOptions::default());
assert!(rule.validate_str("2026-02-23").is_ok());

// Validate date range
let rule = Rule::<String>::DateRange(DateRangeOptions {
format: DateFormat::Iso8601,
allow_time: false,
min: Some("2020-01-01".into()),
max: Some("2030-12-31".into()),
});
assert!(rule.validate_str("2025-06-15").is_ok());
```

**Native type validation** — validate `chrono::NaiveDate` / `jiff::civil::Date` directly:

```rust,ignore
// With chrono feature
use chrono::NaiveDate;
use walrs_validation::Rule;

let min = NaiveDate::from_ymd_opt(2020, 1, 1).unwrap();
let max = NaiveDate::from_ymd_opt(2030, 12, 31).unwrap();
let rule = Rule::<NaiveDate>::Range { min, max };

let date = NaiveDate::from_ymd_opt(2025, 6, 15).unwrap();
assert!(rule.validate_date(&date).is_ok());
```

When both features are enabled, `chrono` takes precedence for string parsing.

## License

MIT & Apache-2.0
2 changes: 2 additions & 0 deletions crates/validation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
//! - `Rule::Uri` - Configurable URI validation (scheme, relative/absolute)
//! - `Rule::Ip` - Configurable IP address validation (IPv4/IPv6/IPvFuture)
//! - `Rule::Hostname` - Configurable hostname validation (DNS/IP/local/public IPv4)
//! - `Rule::Date` - Configurable date format validation (ISO 8601, US, EU, custom)
//! - `Rule::DateRange` - Date range validation with min/max bounds
//! - `Rule::Step` - Step/multiple validation
//! - `Rule::Custom` - Custom closure-based validation
//!
Expand Down
Loading