7 个版本
0.2.3 | 2022年7月2日 |
---|---|
0.2.2 | 2022年5月25日 |
0.1.2 | 2022年5月4日 |
在 数据结构 中排名第 791
37KB
668 行(不含注释)
type-rules
一个易于约束结构体并恢复错误的工具。
目录
安装
# 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,
}
您可以直接在规则 derive 属性中使用表达式。
例如,您可以直接在规则参数中使用 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());
规则列表
以下是在此包中可以找到的规则列表。
每个规则都有其自己的文档和示例。
检查实现了 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(["apple", "banana", "orange", "pear"], "Value need to be a fruit")
All
:将集合约束为符合指定规则的规则,例如:All(MinLength(1), "You can't use empty string")
RegEx
:检查实现AsRef<str>
(String、&str、...)的类型是否与正则表达式匹配。您需要使用regex
功能才能使用它。例如:RegEx(r"^\S+@\S+\.\S+")
依赖
~0–670KB
~12K SLoC