This is JSON Schema based validation tool using with serde.
You derive Validate
trait, and write validations.
```rust use serde_valid::Validate;
struct SampleStruct { #[validate(minimum = 0)] #[validate(maximum = 10)] val: i32, }
enum SampleEnum { Named { #[validate] a: SampleStruct, }, }
let s = SampleEnum::Named { a: SampleStruct { val: 5 }, };
assert!(s.validate().is_ok()); ```
Serde Valid support standard validation based JSON Schema.
| Type | Serde Valid(validate derive) | Serde Valid(validate trait) | Json Schema |
| :-----: | :----------------------------------- | :----------------------------------------------------- | :----------------------------------------------------------------------------------------------------- |
| String | #[validate(max_length = 5)]
| ValidateMaxLength
| maxLength |
| String | #[validate(min_length = 5)]
| ValidateMinLength
| minLength |
| String | #[validate(pattern = r"^\d{5}$")]
| ValidatePattern
| pattern |
| Numeric | #[validate(maximum = 5)]
| ValidateMaximum
| maximum |
| Numeric | #[validate(minimum = 5)]
| ValidateMinimum
| minimum |
| Numeric | #[validate(exclusive_maximum = 5)]
| ValidateExclusiveMaximum
| exclusiveMaximum |
| Numeric | #[validate(exclusive_minimum = 5)]
| ValidateExclusiveMinimum
| exclusiveMinimum |
| Numeric | #[validate(multiple_of = 5)]
| ValidateMultipleOf
| multipleOf |
| Object | #[validate(max_properties = 5)]
| ValidateMaxProperties
| maxProperties |
| Object | #[validate(min_properties = 5)]
| ValidateMinProperties
| minProperties |
| Array | #[validate(max_items = 5)]
| ValidateMaxItems
| maxItems |
| Array | #[validate(min_items = 5)]
| ValidateMinItems
| minItems |
| Array | #[validate(unique_items)]
| ValidateUniqueItems
| uniqueItems |
| Generic | #[validate(enumerate(5, 10, 15))]
| ValidateEnumerate
| enum |
Serde Valid support complete constructor method using by serde_valid::json::FromJsonValue
trait.
```rust use serde::Deserialize; use serdevalid::Validate; use serdevalid::json::{json, FromJsonValue};
struct SampleStruct { #[validate(maximum = 100)] val: i32, }
// Deserialization and Validation!! π let err = SampleStruct::fromjsonvalue(json!({ "val": 123 })).unwrap_err();
asserteq!(
err.asvalidationerrors().unwrap().tostring(),
json!({
"errors": [],
"properties": {
"val": {
"errors": ["The number must be <= 100
."]
}
}
})
.to_string()
);
```
You can force validation by only deserialization through serde_valid
, and removing serde_json
from Cargo.toml
of your project.
For serialization, provides serde_valid::json::ToJsonString
trait.
```rust use serde::Serialize; use serdevalid::Validate; use serdevalid::json::{json, ToJsonString};
struct SampleStruct { #[validate(maximum = 100)] val: i32, }
asserteq!( SampleStruct{ val: 12i32 }.tojsonstring().unwrap(), json!({ "val": 12i32 }).tojson_string().unwrap() ); ```
For user custom message, Serde Valid provides message_fn
or message
.
```rust use serdejson::json; use serdevalid::Validate;
fn minerrormessage(params: &serdevalid::MinItemsError) -> String { "this is min custom messagefn.".tostring() }
struct SampleStruct {
#[validate(minitems = 4, messagefn(minerrormessage))]
#[validate(max_items = 2, message = "this is max custom message.")]
val: Vec
let s = SampleStruct { val: vec![1, 2, 3] };
asserteq!( s.validate().unwraperr().tostring(), json!({ "errors": [], "properties": { "val": { "errors": [ "this is min custom messagefn.", "this is max custom message." ] } } }) .to_string() ); ```
You can use your custom validation using by #[validate(custom)]
.
```rust use serde_valid::Validate;
fn uservalidation(val: &i32) -> Result<(), serde_valid::validation::Error> { Ok(()) }
struct SampleStruct { #[validate(custom(user_validation))] val: i32, }
let s = SampleStruct { val: 1 };
assert!(s.validate().is_ok()); ```
If you want to check multi fields validation, can use #[rule]
.
```rust use serdejson::json; use serdevalid::Validate;
fn samplerule(val1: &i32, val2: &str) -> Result<(), serdevalid::validation::Error> { Err(serdevalid::validation::Error::Custom( "Rule error.".toowned(), )) }
struct SampleStruct { val1: String, val2: i32, }
let s = SampleStruct { val1: "val1".to_owned(), val2: 1, };
let errors = s.validate().unwrap_err();
asserteq!( errors.tostring(), json!({ "errors": ["Rule error."], "properties": {} }) .to_string() ); ```
If you want to use rule to unnamed fields struct, just like this,
```rust use serdejson::json; use serdevalid::Validate;
fn samplerule(val1: &i32, val2: &str) -> Result<(), serdevalid::validation::Error> { Ok(()) }
struct SampleStruct(i32, String);
let s = SampleStruct(0, "1".to_owned());
assert!(s.validate().is_ok()); ```
By implementing the validation trait, Your original type can uses Serde Valid validations.
```rust use serde_valid::Validate;
struct MyType(String);
impl serdevalid::ValidateMaxLength for MyType { fn validatemaxlength(&self, maxlength: usize) -> Result<(), serdevalid::MaxLengthError> { self.0.validatemaxlength(maxlength) } }
struct SampleStruct { #[validate(max_length = 5)] val: MyType, }
let s = SampleStruct { val: MyType(String::from("ππΊππ½π¨βπ€π¨βπ©βπ§βπ¦")), };
assert!(s.validate().is_ok()); ```
Field errors are output to properties
.
```rust use serdejson::json; use serdevalid::Validate;
struct SampleStruct { #[validate(maximum = 4)] val: u32, }
let s = SampleStruct { val: 5 };
asserteq!(
s.validate().unwraperr().tostring(),
json!({
"errors": [],
"properties": {
"val": {
"errors": ["The number must be <= 4
."]
}
}
})
.tostring()
);
```
Field errors are output to items
. The key for items
is guaranteed to be a string of positive numbers.
```rust use serdejson::json; use serdevalid::Validate;
struct SampleStruct ( #[validate(maximum = 4)] u32, #[validate(maximum = 3)] u32, );
let s = SampleStruct ( 5, 4 );
asserteq!(
s.validate().unwraperr().tostring(),
json!({
"errors": [],
"items": {
"0": {
"errors": ["The number must be <= 4
."]
},
"1": {
"errors": ["The number must be <= 3
."]
}
}
})
.tostring()
);
```
Field errors are output to errors
.
```rust use serdejson::json; use serdevalid::Validate;
struct SampleStruct ( #[validate(maximum = 4)] u32 );
let s = SampleStruct (5);
asserteq!(
s.validate().unwraperr().tostring(),
json!({
"errors": ["The number must be <= 4
."]
})
.tostring()
);
```
Variant errors are output to properties
.
```rust use serdejson::json; use serdevalid::Validate;
enum SampleEnum { Named { #[validate(maximum = 5)] a: i32, #[validate(maximum = 5)] b: i32, }, }
let s = SampleEnum::Named { a: 6, b: 6 };
asserteq!(
s.validate().unwraperr().tostring(),
json!({
"errors": [],
"properties": {
"a": {
"errors": ["The number must be <= 5
."]
},
"b": {
"errors": ["The number must be <= 5
."]
}
}
})
.tostring()
);
```
Variant errors are output to items
. The key for items
is guaranteed to be a string of positive numbers.
```rust use serdejson::json; use serdevalid::Validate;
enum SampleEnum { Unnamed ( #[validate(maximum = 5)] i32, #[validate(maximum = 5)] i32, ), }
let s = SampleEnum::Unnamed ( 6, 6 );
asserteq!(
s.validate().unwraperr().tostring(),
json!({
"errors": [],
"items": {
"0": {
"errors": ["The number must be <= 5
."]
},
"1": {
"errors": ["The number must be <= 5
."]
}
}
})
.tostring()
);
```
Variant errors are output to errors
.
```rust use serdejson::json; use serdevalid::Validate;
enum SampleEnum { NewType ( #[validate(maximum = 5)] i32, ), }
let s = SampleEnum::NewType ( 6 );
asserteq!(
s.validate().unwraperr().tostring(),
json!({
"errors": ["The number must be <= 5
."]
})
.tostring()
);
```