type-rules

Crates.io version docs.rs docs License

A tool to easily constrain a struct and recover errors.

Table of Contents

  1. Install
  2. Basic checking
  3. Advanced checking
  4. Make your own rule
  5. Rules list

Install

```toml

Cargo.toml

[dependencies] type-rules = { version = "0.2.2", features = ["derive", "regex"] } ```

Basic checking

You can declare a struct and impose some constraints on each field and check the validity like this:

```rust use chrono::prelude::; use type_rules::prelude::;

[derive(Validator)]

struct NewUser { #[rule(MaxLength(100), RegEx(r"^\S+@\S+.\S+"))] email: String, #[rule(MinMaxLength(8, 50))] password: String, #[rule(Opt(MaxRange(Utc::now())))] birth_date: Option> }

let newuser = NewUser { email: "examples@examples.com".tostring(), password: "OPw$5%hJ".tostring(), birthdate: None, }; assert!(newuser.checkvalidity().isok()); let newuser = NewUser { email: "examples@examples.com".tostring(), password: "O".tostring(), birthdate: None, }; assert!(newuser.checkvalidity().iserr()); //Value is too short ```

Also works with enums :

```rust use type_rules::prelude::*;

[derive(Validator)]

enum MyEnum { Option1(#[rule(MaxLength(200))] String), Option2 { #[rule(MinMaxRange(1, 10))] integer: u32 }, Option3, } ```

Advanced checking

To check recursively, you can use the Validate rule

```rust use type_rules::prelude::*;

[derive(Validator)]

struct EmailWrapper(#[rule(MaxLength(100), RegEx(r"^\S+@\S+.\S+"))] String);

[derive(Validator)]

struct User { #[rule(Validate())] email: EmailWrapper, #[rule(MinMaxLength(8, 50))] password: String, } ```

You can use expressions directly in rule derive attribute.

For example, you can use const or function directly in the rule parameters:

```rust use type_rules::prelude::; use chrono::prelude::;

[derive(Validator)]

struct BirthDate(#[rule(MaxRange(Utc::now()))] DateTime); ```

```rust use type_rules::prelude::*;

[derive(Validator)]

struct Range { #[rule(MaxRange(self.max))] min: u32, #[rule(MinRange(self.min))] max: u32, }; ```

Or use expressions to express a rule directly. Here is an example of using a rule with more complex values:

```rust use std::env; use type_rules::prelude::*;

fn generatemaxpayloadrule() -> MaxLength { MaxLength(match env::var("MAXPAYLOAD") { Ok(val) => val.parse().unwraporelse(|| 10000), Err() => 10000, }) }

[derive(Validator)]

struct Payload(#[rule(generatemaxpayload_rule())] String); ```

In this case the generate_max_payload_rule function is executed at each check

Make your own rule

If you need a specific rule, just make a tuple struct (or struct if you make the declaration outside the struct definition) that implements the Rule feature :

```rust use type_rules::prelude::*;

struct IsEven();

impl Rule for IsEven { fn check(&self, value: &i32) -> Result<(), String> { if value % 2 == 0 { Ok(()) } else { Err("Value is not even".into()) } } }

[derive(Validator)]

struct MyInteger(#[rule(IsEven())] i32); ```

Rules list

Here a list of the rules you can find in this crate.

Each rule has its own documentation with examples.

Check the length of any type that implements AsRef<str> such as String or &str:

Check the range for anything that implements PartialOrd<Self> like all numeric/floating types or dates with chrono:

Check the size of a Vec<T> :

others :