Releases: jprochazk/garde
v0.20.0
v0.19.2
What's changed
- Fixed a bug introduced in
v0.19.1
that would causegarde
to not compile when compiled with the--no-default-features -F email
.
Full Changelog: v0.19.1...v0.19.2
v0.19.1
v0.19.0
What's Changed
Validate without context
Previously, validate
always required a context parameter, even if it was not actually used. In #102, @lasantosr split the validate
function into validate
and validate_with
, where the former does not require a Context
parameter if Context
implements Default
.
#[derive(garde::Validate)]
struct Foo<'a> {
#[garde(length(min = 1))]
bar: &'a str,
}
Foo { bar: "test" }.validate() // no more `&()`!
Add field matching rule
@darkenmay added a new matches
rule in #110, which adds support for the basic case of matching one field against another in the same struct:
#[derive(garde::Validate)]
struct User<'a> {
#[garde(length(min = 1))]
password: &'a str,
#[garde(matches(password))] // checks if this field equals `password`.
password2: &'a str,
}
User { password: "ferris123", password2: "ferris123" }.validate()
Note that this currently does not work for enums.
Other improvements
- Add Report::into_inner by @lasantosr in #107
- feat: implement
Validate
forCow
by @bonofiglio in #108
New Contributors
- @lasantosr made their first contribution in #102
- @darkenmay made their first contribution in #110
Full Changelog: v0.18.0...v0.19.0
v0.18.0
There are quite a few changes in this release:
- Length modes in #88
- Adapters in #93
- Remove default features, replace with
full
in #95 - Serialize/deserialize
Report
in #90 - Remove empty colon from display impl of
Report
in #91
Some of these are breaking changes. If you are only using the derive functionality and calling validate
, updating should still be as simple as a version bump:
cargo add garde@0.18 -F full
If it isn't, please open an issue!
Length modes
You can now specify what kind of length you wish to validate by adding a new mode
argument to your length
rules. The argument is optional.
#[derive(garde::Validate)]
#[garde(transparent)]
struct Username(
#[garde(
length(bytes, min = 1, max = 100),
length(graphemes, min = 1, max = 25)
)]
String
);
The above validates both bytes (via v.len()
) and graphemes (via v.graphemes().count()
using the unicode-segmentation crate. To understand why the distinction is important, consider the xΜ§Μ‘Μ¬ΜΝΜΜ²Μ»Μ»Μ²Μ ΜͺΜ»ΝΝΜΜΜΜΜΜΜΝΜΜΜ
ΜΜΜΝΜΜΝΝ’ΝΝ
character, which occupies 73 bytes in memory, but is considered a single grapheme.
The available modes are:
simple
, which is the default, and its behavior depends on the type. For strings, it measures the number of bytes, and for collections (such asVec
), it meaures the number of items.bytes
, which usess.len()
, measuring the number of bytes,graphemes
, which usess.graphemes(true).count()
, measuring the number of graphemeschars
, which usess.chars().count()
, measuring the number of unicode scalar valuesutf16
, which usess.encode_utf16().count()
, measuring the number of UTF-16 code units
The original Length
and HasLength
traits have been removed, and replaced by one trait per length mode.
Adapters
Using adapters, it is possible to implement validation rules for 3rd-party types directly in your own crates.
mod my_str_adapter {
#![allow(unused_imports)]
pub use garde::rules::*; // re-export garde's rules
pub mod length {
pub use garde::rules::length::*; // re-export `length` rules
pub mod simple {
// re-implement `simple`, but _only_ for the concrete type &str!
pub fn apply(v: &str, (min, max): (usize, usize)) -> garde::Result {
if !(min..=max).contains(&v.len()) {
Err(garde::Error::new("my custom error message"))
} else {
Ok(())
}
}
}
}
}
Adapters are applied using the adapt
field-level attribute:
#[derive(garde::Validate)]
struct Stuff<'a> {
#[garde(
adapt(my_str_adapter),
length(min = 1),
ascii,
)]
v: &'a str,
}
Now my_str_adapter::length::simple
will be used instead of garde::rules::length::simple
when validating the above type, removing the need for a newtype over str
!
full
feature
Having default features for a crate such as garde
means that downstream users are more likely to end up with those default features in their lockfile with no way to turn them off, resulting in increased compile times in exchange for no benefit. Due to this, the default
feature from garde
has been removed, and we now have a new full
feature which contains everything from the removed default
feature.
To retain all the features previously in default
, enable the full
feature when you update:
cargo add garde@0.18 -F full
I urge you to consider if you really need all of full
, though! There may be parts you're not using, and taking a few minutes to see what is the minimum feature set with which your project compiles is definitely worth it.
Miscellaneous
-
The
Report
type now has implementations ofserde::Deserialize
andserde::Serialize
when theserde
feature is enabled. Note that the implementation ofSerialize
has been updated to make it possible to implement a losslessserialize -> deserialize
roundtrip, which is a breaking change if you were doing something with the serialized reports. -
Validation errors on newtypes previously looked like this:
: length is lower than 1
This is because newtypes report their errors with an empty path, resulting in a lone
:
in the error message. This has now been fixed, and will report as:length is lower than 1
Full changelog
v0.17.0
v0.16.3
Smaller Wasm bundles via js-sys
If the js-sys
feature is enabled, #[garde(pattern)]
will now use js_sys::RegExp
instead of regex::Regex
on the wasm32-unknown-unknown
target. This usually means massive bundle size savings depending on which features you need. The two regex implementations aren't fully compatible, which is why it is opt-in via a feature.
Contributed by @aumetra in #77
Support for newtypes
#[derive(garde::Validate)]
#[garde(transparent)]
struct Username(#[garde(length(min = 3, max = 20))] String);
#[derive(garde::Validate)]
struct User {
// later used with `dive`:
#[garde(dive)]
username: Username,
}
See README.md for more information.
Breaking changes
There were no breaking changes in this release.
Full Changelog: v0.16.2...v0.16.3
v0.16.2
v0.16.1
v0.16.0
What's Changed
- axum_garde: note that app state should impl FromRef for () by @imbolc in #69
- feat: inner option support by @bonofiglio in #70
- [Feat] Supporting f32 and f64 for range by @JulesGuesnon in #71
Breaking changes
The garde::error::Kind
enum has a new variant, None
.
New Contributors
- @imbolc made their first contribution in #69
- @bonofiglio made their first contribution in #70
- @JulesGuesnon made their first contribution in #71
Full Changelog: v0.15.0...v0.16.0