Skip to content

Commit d8e1bd8

Browse files
authored
Merge pull request #131 from Fogapod/stdlib-static-regex
2 parents 8fc1119 + ff67b53 commit d8e1bd8

File tree

5 files changed

+46
-12
lines changed

5 files changed

+46
-12
lines changed

README.md

-2
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,6 @@ Contributing to `garde` only requires a somewhat recent version of [`Rust`](http
518518

519519
This repository also makes use of the following tools, but they are optional:
520520
- [`insta`](https://insta.rs/) for snapshot testing ([tests/rules](./garde_derive_tests/tests/rules/)).
521-
- [`just`](https://just.systems/) for running recipes defined in the [`justfile`](./justfile).
522-
Run `just -l` to see what recipes are available.
523521

524522
### License
525523

garde/src/rules/pattern.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,22 @@
1111
//! ```
1212
//!
1313
//! Alternatively, it can be an expression of type implementing [`Matcher`] or one that dereferences to a [`Matcher`].
14-
//! [`Matcher`] is implemented for `regex::Regex` (if the `regex` feature is enabled) and `once_cell::sync::Lazy<T>` with any `T: Matcher`.
14+
//! [`Matcher`] is implemented for `regex::Regex` (if the `regex` feature is enabled) and `std::sync::LazyLock<T>` / `once_cell::sync::Lazy<T>` with any `T: Matcher`.
1515
//! Please note that the expression will be evaluated each time `validate` is called, so avoid doing any expensive work in the expression.
16-
//! If the work is unavoidable, at least try to amortize it, such as by using `once_cell::Lazy` or the nightly-only `std::sync::LazyLock`.
16+
//! If the work is unavoidable, at least try to amortize it, such as by using `std::sync::LazyLock` or `once_cell::Lazy`.
17+
//!
18+
//! ```rust
19+
//! use std::sync::LazyLock;
20+
//! use regex::Regex;
21+
//!
22+
//! static LAZY_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"[a-zA-Z0-9][a-zA-Z0-9_]+").unwrap());
23+
//!
24+
//! #[derive(garde::Validate)]
25+
//! struct Test {
26+
//! #[garde(pattern(LAZY_RE))]
27+
//! v: String,
28+
//! }
29+
//! ```
1730
//!
1831
//! ```rust
1932
//! use once_cell::sync::Lazy;
@@ -50,6 +63,18 @@ pub trait Matcher: AsStr {
5063
fn is_match(&self, haystack: &str) -> bool;
5164
}
5265

66+
impl<T: Matcher> Matcher for std::sync::LazyLock<T> {
67+
fn is_match(&self, haystack: &str) -> bool {
68+
std::sync::LazyLock::force(self).is_match(haystack)
69+
}
70+
}
71+
72+
impl<T: AsStr> AsStr for std::sync::LazyLock<T> {
73+
fn as_str(&self) -> &str {
74+
std::sync::LazyLock::force(self).as_str()
75+
}
76+
}
77+
5378
pub trait Pattern {
5479
fn validate_pattern<M: Matcher>(&self, matcher: &M) -> bool;
5580
}
@@ -77,7 +102,7 @@ impl<T: Pattern> Pattern for Option<T> {
77102
))]
78103
#[doc(hidden)]
79104
pub mod regex_js_sys {
80-
pub use ::js_sys::RegExp;
105+
pub use js_sys::RegExp;
81106

82107
use super::*;
83108

@@ -117,7 +142,7 @@ pub mod regex_js_sys {
117142
unsafe impl<T> Send for SyncWrapper<T> {}
118143
unsafe impl<T> Sync for SyncWrapper<T> {}
119144

120-
pub type StaticPattern = once_cell::sync::Lazy<SyncWrapper<RegExp>>;
145+
pub type StaticPattern = std::sync::LazyLock<SyncWrapper<RegExp>>;
121146

122147
#[macro_export]
123148
macro_rules! __init_js_sys_pattern {
@@ -134,9 +159,9 @@ pub mod regex_js_sys {
134159
#[cfg(feature = "regex")]
135160
#[doc(hidden)]
136161
pub mod regex {
137-
pub use ::regex::Regex;
162+
pub use regex::Regex;
138163

139-
use super::*;
164+
use super::{AsStr, Matcher};
140165

141166
impl Matcher for Regex {
142167
fn is_match(&self, haystack: &str) -> bool {
@@ -162,7 +187,7 @@ pub mod regex {
162187
}
163188
}
164189

165-
pub type StaticPattern = once_cell::sync::Lazy<Regex>;
190+
pub type StaticPattern = std::sync::LazyLock<Regex>;
166191

167192
#[macro_export]
168193
macro_rules! __init_pattern {

garde/tests/rules/pattern.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ use regex::Regex;
33
use super::util;
44

55
mod sub {
6+
use std::sync::LazyLock;
7+
68
use once_cell::sync::Lazy;
79

810
use super::*;
911

10-
pub static LAZY_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^abcd|efgh$").unwrap());
12+
pub static LAZY_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^abcd|efgh$").unwrap());
13+
pub static LAZY_RE_ONCE_CELL: Lazy<Regex> = Lazy::new(|| Regex::new(r"^abcd|efgh$").unwrap());
1114
}
1215

1316
#[derive(Debug, garde::Validate)]
@@ -18,6 +21,9 @@ struct Test<'a> {
1821
#[garde(pattern(sub::LAZY_RE))]
1922
field_path: &'a str,
2023

24+
#[garde(pattern(sub::LAZY_RE_ONCE_CELL))]
25+
field_path_once_cell: &'a str,
26+
2127
#[garde(pattern(create_regex()))]
2228
field_call: &'a str,
2329

@@ -46,12 +52,14 @@ fn pattern_valid() {
4652
Test {
4753
field: "abcd",
4854
field_path: "abcd",
55+
field_path_once_cell: "abcd",
4956
field_call: "abcd",
5057
inner: &["abcd"],
5158
},
5259
Test {
5360
field: "efgh",
5461
field_path: "efgh",
62+
field_path_once_cell: "abcd",
5563
field_call: "efgh",
5664
inner: &["efgh"],
5765
},
@@ -68,12 +76,14 @@ fn pattern_invalid() {
6876
Test {
6977
field: "dcba",
7078
field_path: "dcba",
79+
field_path_once_cell: "abcd",
7180
field_call: "dcba",
7281
inner: &["dcba"]
7382
},
7483
Test {
7584
field: "hgfe",
7685
field_path: "hgfe",
86+
field_path_once_cell: "abcd",
7787
field_call: "hgfe",
7888
inner: &["hgfe"]
7989
}

garde/tests/rules/snapshots/rules__rules__pattern__pattern_invalid.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ expression: snapshot
55
Test {
66
field: "dcba",
77
field_path: "dcba",
8+
field_path_once_cell: "abcd",
89
field_call: "dcba",
910
inner: [
1011
"dcba",
@@ -18,6 +19,7 @@ inner[0]: does not match pattern /^abcd|efgh$/
1819
Test {
1920
field: "hgfe",
2021
field_path: "hgfe",
22+
field_path_once_cell: "abcd",
2123
field_call: "hgfe",
2224
inner: [
2325
"hgfe",
@@ -27,5 +29,3 @@ field: does not match pattern /^abcd|efgh$/
2729
field_call: does not match pattern /^abcd|efgh$/
2830
field_path: does not match pattern /^abcd|efgh$/
2931
inner[0]: does not match pattern /^abcd|efgh$/
30-
31-

garde/tests/ui/compile-fail/pattern_mismatched_types.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ error[E0277]: the trait bound `&str: Matcher` is not satisfied
88
| ^^^ the trait `Matcher` is not implemented for `&str`
99
|
1010
= help: the following other types implement trait `Matcher`:
11+
LazyLock<T>
1112
Regex
1213
once_cell::sync::Lazy<T>
1314
note: required by a bound in `garde::rules::pattern::apply`

0 commit comments

Comments
 (0)