6个版本

0.2.3 2022年7月2日
0.2.2 2022年5月25日
0.1.2 2022年5月4日

#rule中排名52

每月下载量40
type-rules中使用

MIT/Apache

14KB
192

type-rules

一个用于轻松约束结构和恢复错误的工具。

目录

  1. 安装
  2. 基本检查
  3. 高级检查
  4. 创建自己的规则
  5. 规则列表

安装

# Cargo.toml
[dependencies]
type-rules = { version = "0.2.3", features = ["derive", "regex", "serde"] }

基本检查

您可以通过这种方式声明一个结构体并对每个字段施加一些约束并检查其有效性

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<DateTime<Utc>>
}

let new_user = NewUser {
    email: "[email protected]".to_string(),
    password: "OPw$5%hJ".to_string(),
    birth_date: None,
};
assert!(new_user.check_validity().is_ok());
let new_user = NewUser {
    email: "[email protected]".to_string(),
    password: "O".to_string(),
    birth_date: None,
};
assert!(new_user.check_validity().is_err()); //Value is too short

也适用于枚举

use type_rules::prelude::*;

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

高级检查

要递归检查,可以使用Validate规则

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,
}

您可以直接在规则派生属性中使用表达式。

例如,您可以直接在规则参数中使用const或函数

use type_rules::prelude::*;
use chrono::prelude::*;

#[derive(Validator)]
struct BirthDate(#[rule(MaxRange(Utc::now()))] DateTime<Utc>);
use type_rules::prelude::*;

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

或者使用表达式直接表达规则。以下是一个使用更复杂值的规则的示例

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

fn generate_max_payload_rule() -> MaxLength {
    MaxLength(match env::var("MAX_PAYLOAD") {
        Ok(val) => val.parse().unwrap_or_else(|_| 10000),
        Err(_) => 10000,
    })
}

#[derive(Validator)]
struct Payload(#[rule(generate_max_payload_rule())] String);

在这种情况下,generate_max_payload_rule函数在每次检查时都会执行

创建自己的规则

如果您需要特定的规则,只需创建一个实现Rule特征的元组结构体(或结构体,如果声明在结构定义外部)即可

use type_rules::prelude::*;

struct IsEven();

impl Rule<i32> 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);

有效包装器

Valid是任何实现Validator的类型包装器,它允许在编译时确保内部类型已被验证。

使用serde功能,Valid可以带有有效性检查进行序列化和反序列化。

use type_rules::prelude::*;

#[derive(Validator)]
struct NewUser {
   #[rule(MinMaxLength(3, 50))]
   username: String,
   #[rule(MinMaxLength(8, 100))]
   password: String,
}

fn do_something(user: Valid<NewUser>) {
   // No need to check if user is valid
}

let new_user = NewUser {
   username: "example".to_string(),
   password: "OPw$5%hJJ".to_string(),
};
do_something(Valid::new(new_user).unwrap());

规则列表

以下是在此crate中可以找到的规则列表。

每个规则都有其自己的文档和示例。

检查实现了AsRef<str>的类型(如String&str)的长度

  • MinLength:最小长度,例如:MinLength(5)
  • MaxLength:最大长度,例如:MaxLength(20)
  • MinMaxLength:最小和最大长度,例如:MinMaxLength(5, 20)

检查任何实现了 PartialOrd<Self> 的类型,例如所有数值/浮点类型或使用 chrono 的日期

  • MinRange:最小范围,例如:MinRange(5)
  • MaxRange:最大范围,例如:MaxRange(20)
  • MinMaxRange:最小和最大范围,例如:MinMaxRange(5, 20)

检查 Vec<T> 的大小

  • MinSize:最小大小,例如:MinSize(5)
  • MaxSize:最大大小,例如:MaxSize(20)
  • MinMaxSize:最小和最大大小,例如:MinMaxSize(5, 20)

其他

  • Opt:对 Option 的内部值应用另一规则,例如:Opt(MinMaxRange(1, 4))
  • And:确保两个其他规则都是 Ok 的规则,例如:And(MaxLength(1000), RegEx(r"^\S+@\S+\.\S+"))
  • Or:对两个其他规则应用 Or 条件,例如:Or(MaxRange(-1), MinRange(1))
  • Eval:将任何类型约束到谓词的规则,例如:Eval(predicate, "Error message")
  • Validate:递归检查,例如:Validate()
  • In:将类型约束在集合中的规则,例如:in In(["apple", "banana", "orange", "pear"], "Value need to be a fruit")
  • All:将集合约束为验证指定规则的规则,例如:All(MinLength(1), "You can't use empty string")
  • RegEx:检查实现 AsRef<str>(字符串,&str,...)的类型是否匹配正则表达式。您需要使用 regex 功能。例如:RegEx(r"^\S+@\S+\.\S+")

依赖

~1.5MB
~35K SLoC