50 个版本 (23 个重大更新)
0.24.0 | 2024年6月22日 |
---|---|
0.22.0 | 2024年6月15日 |
0.19.0 | 2024年3月2日 |
0.16.3 | 2023年7月30日 |
0.6.2 | 2022年7月31日 |
#79 in 编码
每月下载 30,825 次
在 17 个crate中使用 (直接使用11个)
220KB
4.5K SLoC
Serde Valid
这是一个基于 JSON Schema 的,使用 serde 的验证工具。
用法
您派生 Validate
特性,并编写验证。
use serde_valid::Validate;
#[derive(Validate)]
struct Data {
#[validate(minimum = 0)]
#[validate(maximum = 10)]
val: i32,
}
#[derive(Validate)]
enum DataEnum {
Named {
#[validate]
a: Data,
},
}
let s = DataEnum::Named {
a: Data { val: 5 },
};
assert!(s.validate().is_ok());
特性标志
toml
- 提供以toml
格式的序列化和反序列化。yaml
- 提供以yaml
格式的序列化和反序列化。i128
- 支持i128
/u128
类型(默认)。fluent
- 使用 fluent 提供本地化。
验证
Serde Valid 支持基于 JSON Schema 的标准验证。
类型 | Serde Valid(验证派生) | Serde Valid(验证特性) | JSON Schema |
---|---|---|---|
字符串 | #[验证(最大长度= 5)] |
ValidateMaxLength |
maxLength |
字符串 | #[验证(最小长度= 5)] |
ValidateMinLength |
minLength |
字符串 | #[验证(模式= r"^\d{5}$")] |
ValidatePattern |
模式 |
数字 | #[验证(最大值= 5)] |
ValidateMaximum |
最大值 |
数字 | #[验证(最小值= 5)] |
ValidateMinimum |
最小值 |
数字 | #[验证(最大值(不包括)= 5)] |
ValidateExclusiveMaximum |
exclusiveMaximum |
数字 | #[验证(最小值(不包括)= 5)] |
ValidateExclusiveMinimum |
exclusiveMinimum |
数字 | #[验证(倍数= 5)] |
ValidateMultipleOf |
multipleOf |
对象 | #[验证(最大属性数= 5)] |
ValidateMaxProperties |
maxProperties |
对象 | #[验证(最小属性数= 5)] |
ValidateMinProperties |
minProperties |
数组 | #[验证(最大项数= 5)] |
ValidateMaxItems |
maxItems |
数组 | #[验证(最小项数= 5)] |
ValidateMinItems |
minItems |
数组 | #[验证(唯一项)] |
ValidateUniqueItems |
uniqueItems |
泛型 | #[验证(枚举= [5, 10, 15])] |
ValidateEnumerate |
enum |
此外,[serde_valid::utils][module@crate::utils] 提供了 JSON Schema 规范中未描述的验证类型。
类型 | Serde Valid(验证派生) | Serde Valid(验证函数) |
---|---|---|
持续时间 | #[验证(自定义= 持续时间最大值(SECOND))] |
持续时间最大值 |
持续时间 | #[验证(自定义= 持续时间最小值(ZERO))] |
持续时间最小值 |
持续时间 | #[验证(自定义= 持续时间最大值(不包括)(SECOND))] |
持续时间最大值(不包括) |
持续时间 | #[验证(自定义= 持续时间最小值(不包括)(ZERO))] |
持续时间最小值(不包括) |
完整构造函数(反序列化)
Serde Valid 支持使用 serde_valid::json::FromJsonValue
特性完全构造方法。
use serde::Deserialize;
use serde_valid::Validate;
use serde_valid::json::{json, FromJsonValue};
#[derive(Debug, Deserialize, Validate)]
struct Data {
#[validate(maximum = 100)]
val: i32,
}
// Deserialization and Validation!! 🚀
let err = Data::from_json_value(json!({ "val": 123 })).unwrap_err();
assert_eq!(
err.to_string(),
json!({
"errors": [],
"properties": {
"val": {
"errors": ["The number must be `<= 100`."]
}
}
})
.to_string()
);
您可以通过仅使用 serde_valid
进行反序列化来强制进行验证,并从项目的 Cargo.toml
中删除 serde_json
。
序列化
对于序列化,提供了 serde_valid::json::ToJsonString
特性。
use serde::Serialize;
use serde_valid::Validate;
use serde_valid::json::{json, ToJsonString};
#[derive(Debug, Serialize, Validate)]
struct Data {
#[validate(maximum = 100)]
val: i32,
}
assert_eq!(
Data{ val: 12i32 }.to_json_string().unwrap(),
json!({ "val": 12i32 }).to_json_string().unwrap()
);
自定义消息
对于用户自定义消息,Serde Valid 提供了 message_fn
或 message
。
use serde_json::json;
use serde_valid::Validate;
#[inline]
fn min_error_message(_params: &serde_valid::MinItemsError) -> String {
"this is custom message_fn.".to_string()
}
#[derive(Validate)]
struct Data {
#[validate(min_items = 4, message_fn = min_error_message)]
#[validate(max_items = 2, message = "this is custom message.")]
val: Vec<i32>,
}
let s = Data { val: vec![1, 2, 3] };
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": [],
"properties": {
"val": {
"errors": [
"this is custom message_fn.",
"this is custom message."
]
}
}
})
.to_string()
);
流畅本地化
需要fluent
功能。您还可以通过使用 fluent
功能来使用 fluent 本地化。
允许以下属性
#[验证(..., fluent("message-id",key1=value1, ...))]
#[验证(...,message_l10n= fluent("message-id",key1=value1, ...))]
use unic_langid::LanguageIdentifier;
use serde_json::json;
use serde_valid::{fluent::Localize, Validate};
#[derive(Validate)]
struct Data (
#[validate(min_length = 3, fluent("name-min-length", min_length = 3))]
String,
);
assert_eq!(
Data("田中".to_string()).validate()
.unwrap_err()
.localize(&get_bundle("name-min-length = 名前の長さは { $min_length } 文字以上でないといけません。"))
.to_string(),
json!({
"errors": ["名前の長さは \u{2068}3\u{2069} 文字以上でないといけません。"]
})
.to_string()
);
自定义验证
单错误验证
您可以使用 #[validate(custom = ...)]
使用您自定义的验证。
use serde_valid::Validate;
fn user_validation(_val: &i32) -> Result<(), serde_valid::validation::Error> {
Ok(())
}
#[derive(Validate)]
struct Data {
#[validate(custom = user_validation)]
val: i32,
}
let s = Data { val: 1 };
assert!(s.validate().is_ok());
您也可以使用闭包。
use serde_valid::Validate;
fn user_validation(_val: &i32, param1: bool) -> Result<(), serde_valid::validation::Error> {
Ok(())
}
#[derive(Validate)]
struct Data {
#[validate(custom = |v| user_validation(v, true))]
val: i32,
}
let s = Data { val: 1 };
assert!(s.validate().is_ok());
自定义验证适用于处理在 JSON Schema 中未定义的便利验证。serde_valid::utils::*
为特定类型提供了便利函数。
use serde_json::json;
use serde_valid::Validate;
use serde_valid::utils::{duration_maximum, duration_minimum};
#[derive(Validate)]
struct Data {
#[validate(custom = duration_maximum(std::time::Duration::from_micros(5)))]
#[validate(custom = duration_minimum(std::time::Duration::from_micros(0)))]
val1: std::time::Duration,
}
let s = Data {
val1: std::time::Duration::from_micros(1),
};
assert!(s.validate().is_ok());
多错误验证
如果您想在自定义验证方法中使用多个错误,可以使用与单错误相同的 #[validate(custom = ...)]
。
use serde_valid::Validate;
// 🚀 Just change the return type from `Result<(), Error>` to `Result<(), Vec<Error>>` !!
fn user_validation(_val: &i32) -> Result<(), Vec<serde_valid::validation::Error>> {
Ok(())
}
#[derive(Validate)]
struct Data {
#[validate(custom = user_validation)]
val: i32,
}
let s = Data { val: 1 };
assert!(s.validate().is_ok());
多字段验证
现在,您可以使用 #[validate(custom = ...)]
进行多字段验证。
use serde_json::json;
use serde_valid::Validate;
fn sample_validation(val1: i32, val2: &str) -> Result<(), serde_valid::validation::Error> {
Ok(())
}
#[derive(Validate)]
#[validate(custom = |s| sample_validation(s.val1, &s.val2))]
struct Data {
val1: i32,
val2: String,
}
let s = Data {
val1: 1,
val2: "val2".to_owned(),
};
assert!(s.validate().is_ok());
验证特质
通过实现验证特质,您的原始类型可以使用 Serde Valid 验证。
use serde_valid::Validate;
struct MyType(String);
impl serde_valid::ValidateMaxLength for MyType {
fn validate_max_length(&self, max_length: usize) -> Result<(), serde_valid::MaxLengthError> {
self.0.validate_max_length(max_length)
}
}
#[derive(Validate)]
struct Data {
#[validate(max_length = 5)]
val: MyType,
}
let s = Data {
val: MyType(String::from("😍👺🙋🏽👨🎤👨👩👧👦")),
};
assert!(s.validate().is_ok());
验证错误格式
命名结构体
字段错误输出到 properties
。
use serde_json::json;
use serde_valid::Validate;
#[derive(Validate)]
struct Data {
#[validate(maximum = 4)]
val: u32,
}
let s = Data { val: 5 };
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": [],
"properties": {
"val": {
"errors": ["The number must be `<= 4`."]
}
}
})
.to_string()
);
未命名结构体
字段错误输出到 items
。对于 items
的键保证是正数字符串。
use serde_json::json;
use serde_valid::Validate;
#[derive(Validate)]
struct Data (
#[validate(maximum = 4)] u32,
#[validate(maximum = 3)] u32,
);
let s = Data ( 5, 4 );
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": [],
"items": {
"0": {
"errors": ["The number must be `<= 4`."]
},
"1": {
"errors": ["The number must be `<= 3`."]
}
}
})
.to_string()
);
新类型
字段错误输出到 errors
。
use serde_json::json;
use serde_valid::Validate;
#[derive(Validate)]
struct Data (
#[validate(maximum = 4)] u32
);
let s = Data (5);
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": ["The number must be `<= 4`."]
})
.to_string()
);
命名枚举
变体错误输出到 properties
。
use serde_json::json;
use serde_valid::Validate;
#[derive(Validate)]
enum Data {
Named {
#[validate(maximum = 5)]
a: i32,
#[validate(maximum = 5)]
b: i32,
},
}
let s = Data::Named { a: 6, b: 6 };
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": [],
"properties": {
"a": {
"errors": ["The number must be `<= 5`."]
},
"b": {
"errors": ["The number must be `<= 5`."]
}
}
})
.to_string()
);
未命名枚举
变体错误输出到 items
。对于 items
的键保证是正数字符串。
use serde_json::json;
use serde_valid::Validate;
#[derive(Validate)]
enum Data {
Unnamed (
#[validate(maximum = 5)] i32,
#[validate(maximum = 5)] i32,
),
}
let s = Data::Unnamed ( 6, 6 );
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": [],
"items": {
"0": {
"errors": ["The number must be `<= 5`."]
},
"1": {
"errors": ["The number must be `<= 5`."]
}
}
})
.to_string()
);
新类型枚举
变体错误输出到 errors
。
use serde_json::json;
use serde_valid::Validate;
#[derive(Validate)]
enum Data {
NewType (
#[validate(maximum = 5)] i32,
),
}
let s = Data::NewType ( 6 );
assert_eq!(
s.validate().unwrap_err().to_string(),
json!({
"errors": ["The number must be `<= 5`."]
})
.to_string()
);
依赖
~5–7.5MB
~132K SLoC