Serde Valid

This is JSON Schema based validation tool using with serde.

Usage

You derive Validate trait, and write validations.

```rust use serde_valid::Validate;

[derive(Validate)]

struct SampleStruct { #[validate(minimum = 0)] #[validate(maximum = 10)] val: i32, }

[derive(Validate)]

enum SampleEnum { Named { #[validate] a: SampleStruct, }, UnNamed( #[validate(minimum = 0)] #[validate(maximum = 10)] i32, ), }

let s = SampleEnum::Named { a: SampleStruct { val: 5 }, };

assert!(s.validate().is_ok()); ```

Validations

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 |

Complete Constructor (Deserialization)

Serde Valid support complete constructor method using by [serde_valid::json::FromJson][FromJson] trait.

```rust use serde::Deserialize; use serdevalid::Validate; use serdevalid::json::{json, FromJson};

[derive(Debug, Deserialize, Validate)]

struct SampleStruct { #[validate(maximum = 100)] val: i32, }

// Deserialization and Validation!! πŸš€ let err = SampleStruct::fromjsonvalue(json!({ "val": 123 })).unwrap_err();

asserteq!( serdejson::tovalue(err.asvalidation_errors().unwrap()).unwrap(), json!({ "val": [ "the number must be <= 100." ] }) ); ```

You can force validation by only deserialization through serde_valid, and removing serde_json from Cargo.toml of your project.

Serialization

For serialization, provides serde_valid::json::ToJson trait.

```rust use serde::Serialize; use serdevalid::Validate; use serdevalid::json::{json, ToJson};

[derive(Debug, Serialize, Validate)]

struct SampleStruct { #[validate(maximum = 100)] val: i32, }

asserteq!( SampleStruct{ val: 12i32 }.tojsonstring().unwrap(), json!({ "val": 12i32 }).tojson_string().unwrap() ); ```

Custom Message

For user custom message, Serde Valid provides message_fn or message.

```rust use serdejson::json; use serdevalid::Validate;

fn minerrormessage(params: &serdevalid::MinItemsErrorParams) -> String { "this is min custom messagefn.".tostring() }

[derive(Validate)]

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!( serdejson::tostring(&s.validate().unwraperr()).unwrap(), serdejson::tostring(&json!({ "val": [ "this is min custom message_fn.", "this is max custom message." ] })) .unwrap() ); ```

Custom method

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(()) }

[derive(Validate)]

struct SampleStruct { #[validate(custom(user_validation))] val: i32, }

let s = SampleStruct { val: 1 };

assert!(s.validate().is_ok()); ```

Rules

If you want to check multi fields validation, you 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 is added to the first arg of the rulemethod.".to_owned(), )) }

[derive(Validate)]

[rule(sample_rule(val2, val1))]

struct SampleStruct { val1: String, val2: i32, }

let s = SampleStruct { val1: "val1".to_owned(), val2: 1, };

asserteq!( serdejson::tostring(&s.validate().unwraperr()).unwrap(), serdejson::tostring(&json!({ "val2": [ "Rule error is added to the first arg of the rule_method." ] })) .unwrap() ); ```

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(()) }

[derive(Validate)]

[rule(sample_rule(0, 1))]

struct SampleStruct(i32, String);

let s = SampleStruct(0, "1".to_owned());

assert!(s.validate().is_ok()); ```

Validate Traits

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::MaxLengthErrorParams> { self.0.validatemaxlength(maxlength) } }

impl serdevalid::ValidateMinLength for MyType { fn validateminlength(&self, minlength: usize) -> Result<(), serdevalid::MinLengthErrorParams> { self.0.validateminlength(minlength) } }

[derive(Validate)]

struct SampleStruct { #[validate(minlength = 5)] #[validate(maxlength = 5)] val: MyType, }

let s = SampleStruct { val: MyType(String::from("πŸ˜πŸ‘ΊπŸ™‹πŸ½πŸ‘¨β€πŸŽ€πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦")), };

assert!(s.validate().is_ok()); ```