Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
G

garde

> 编程语言
Open source

A powerful validation library for Rust

879 stars0 likes0 views
WebsiteGitHub

About

A powerful validation library for Rust

Garde   Documentation Latest Version

A Rust validation library

  • Basic usage example
  • Validation rules
  • Length modes
  • Inner type validation
  • I18n
  • Newtypes
  • Handling Option
  • Custom validation
  • Conditional validation
  • Context/Self access
  • Implementing rules
  • Implementing Validate
  • Rule adapters
  • Integration with web frameworks
  • Feature flags
  • Why garde?

Basic usage example

To get started, install garde:

cargo add garde -F full

And attach the Validate derive to your type. garde will generate an implementation of the Validate trait for you, allowing you to call the validate method.

Here's what that looks like in full:

rust
use garde::{Validate, Valid};

#[derive(Validate)]
struct User {
    #[garde(ascii, length(min=3, max=25))]
    username: &'a str,
    #[garde(length(min=15))]
    password: &'a str,
}

let user = User {
    username: "test",
    password: "not_a_very_good_password",
};

if let Err(e) = user.validate() {
    println!("invalid user: {e}");
}

Garde can also validate enums:

rust
use garde::{Validate, Valid};

#[derive(Validate)]
enum Data {
    Struct {
        #[garde(range(min=-10, max=10))]
        field: i32,
    },
    Tuple(
        #[garde(ascii)]
        String
    ),
}

let data = Data::Struct { field: 100 };
if let Err(e) = data.validate() {
    println!("invalid data: {e}");
}

Available validation rules

name format validation feature flag
required #[garde(required)] is value set -
ascii #[garde(ascii)] only contains ASCII -
alphanumeric #[garde(alphanumeric)] only letters and digits -
email #[garde(email)] an email according to the HTML5 spec[^1] email
url #[garde(url)] a URL url
ip #[garde(ip)] an IP address (either IPv4 or IPv6) -
ipv4 #[garde(ipv4)] an IPv4 address -
ipv6 #[garde(ipv6)] an IPv6 address -
credit card #[garde(credit_card)] a credit card number credit-card
phone number #[garde(phone_number)] a phone number phone-number
length #[garde(length(, min=, max=, equal=)] a container with length in min..=max or equal -
matches #[garde(matches())] a field matches another field -
range #[garde(range(min=, max=, equal=))] a number in the range min..=max or equal -
contains #[garde(contains())] a string-like value containing a substring -
prefix #[garde(prefix())] a string-like value prefixed by some string -
suffix #[garde(suffix())] a string-like value suffixed by some string -
pattern #[garde(pattern(""))] a string-like value matching some regular expression regex
pattern #[garde(pattern())] a string-like value matched by some Matcher -
dive #[garde(dive)] nested validation, calls validate on the value -
skip #[garde(skip)] skip validation -
custom #[garde(custom())] a custom validator -
if #[garde(if(cond = , ...))] conditional validation, applies rules only when condition is true -

Additional notes:

  • required is only available for Option fields.
  • dive accepts an optional context: #[garde(dive(self.other_field))]
  • The `` argument for length is explained here
  • For length and range:
    • If equal is defined, min and max must be omitted.
    • Assuming equal is omitted, either min or max may be omitted, but not both.
    • min and max use an inclusive upper bound (min..=max). Setting min == max is equivalent to using equal.
  • For contains, prefix, and suffix, the pattern must be a string literal, because the Pattern API is currently unstable.
  • For if conditional validation:
    • The condition expression can access self fields and context variables (e.g., ctx).
    • Multiple rules can be specified with the condition: if(cond = expr, rule1, rule2, ...).
    • The cond = expr argument may appear anywhere in the rule.
    • Multiple conditional blocks can be used on the same field.
    • Conditional validation can be nested with inner.
  • Garde does not enable the default features of the regex crate
    • For pattern("") rules, if you need extra regex features (e.g. Unicode) or better performance, add regex = "1" to your Cargo.toml, both in [dependencies] AND [build-dependencies].

If most of the fields on your struct are annotated with #[garde(skip)], you may use #[garde(allow_unvalidated)] instead:

rust
#[derive(garde::Validate)]
struct Foo {
    #[garde(length(min = 1))]
    a: &'a str,

    #[garde(skip)]
    b: &'a str, // this field will not be validated
}

#[derive(garde::Validate)]
#[garde(allow_unvalidated)]
struct Bar {
    #[garde(length(min = 1))]
    a: &'a str,

    b: &'a str, // this field will not be validated
                // note the lack of `#[garde(skip)]`
}

Length modes

The length rule accepts an optional mode argument, which determines what kind of length it will validate.

The options are:

  • simple
  • bytes
  • graphemes
  • utf16
  • chars

The simple is the default used when the mode argument is omitted. The meaning of "simple length" depends on the type. It is currently implemented for strings, where it validates the number of bytes, and std::collections, where it validates the number of items.

rust
#[derive(garde::Validate)]
struct Foo {
    #[garde(length(min = 1, max = 100))]
    string: String,

    #[garde(length(min = 1, max = 100))]
    collection: Vec
}

The bytes, graphemes, utf16, and chars exist mostly for string validation:

  • bytes validates the number of bytes
  • graphemens uses the unicode-segmentation crate, and validates the number of graphemes
  • utf16 uses encode_utf16, and validates the number of UTF-16 code points
  • chars uses chars, and validates the number of unicode scalar values
rust
#[derive(garde::Validate)]
struct Foo {
    #[garde(length(bytes, min = 1, max = 100))]
    a: String, // `a.len()`
    
    #[garde(length(graphemes, min = 1, max = 100))]
    b: String, // `b.graphemes().count()`
    
    #[garde(length(utf16, min = 1, max = 100))]
    c: String, // `c.encode_utf16().count()`
    
    #[garde(length(chars, min = 1, max = 100))]
    d: String, // `d.chars().count()`
}

Inner type validation

If you need to validate the "inner" type of a container, such as the String in Vec, then use the inner modifier:

rust
#[derive(garde::Validate)]
struct Test {
    #[garde(
        length(min = 1),
        inner(ascii, length(min = 1)), // wrap the rule in `inner`
    )]
    items: Vec,
}

The above type would fail validation if:

  • the Vec is empty
  • any of the inner String elements is empty
  • any of the inner String elements contains non-ASCII characters

To validate a deeply-nested type, such as Vec>, the inner modifier must be nested for each level of generics:

rust
#[derive(garde::Validate)]
struct Test {
    #[garde(
        length(min = 1), // applies to `Vec`
        inner(inner(ascii, length(min = 1))), // applies to `String`
    )]
    items: Vec>,
}

You can apply separate rules to every level of the nested type:

rust
#[derive(garde::Validate)]
struct Test {
    #[garde(
        length(min = 1), // applies to `Vec`
        inner(required), // applies to `Option`
        inner(inner(ascii, length(min = 1))), // applies to `String`
    )]
    items: Vec>,
}

I18n

Error messages produced by rules may be customized by implementing [I18n]:

…

The default implementation is [i18n::DefaultI18n], which produces error mess

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Rustrustvalidation

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言