Trait validify::Validify

source ·
pub trait Validify: Modify + Validate + Sized + From<Self::Payload> {
    type Payload: DeserializeOwned + Validate;

    // Provided methods
    fn validify(payload: Self::Payload) -> Result<Self, ValidationErrors> { ... }
    fn validify_self(&mut self) -> Result<(), ValidationErrors> { ... }
}
Expand description

Deriving Validify allows you to modify structs before they are validated by providing a out of the box validation implementations as well as the ability to write custom ones. It also generates a payload struct for the deriving struct, which can be used when deserialising web payloads. The payload struct is just a copy of the original, except will all the fields being Options. This enables the payload to be fully deserialized (given that all existing fields are of the correct type) before being validated to allow for better validation errors.

Example

use validify::Validify;

#[derive(Debug, Clone, serde::Deserialize, Validify)]
struct Testor {
    #[modify(lowercase, trim)]
    #[validate(length(equal = 8))]
    pub a: String,
    #[modify(trim, uppercase)]
    pub b: Option<String>,
    #[modify(custom(do_something))]
    pub c: String,
    #[modify(custom(do_something))]
    pub d: Option<String>,
    #[validify]
    pub nested: Nestor,
}

#[derive(Debug, Clone, serde::Deserialize, Validify)]
struct Nestor {
    #[modify(trim, uppercase)]
    #[validate(length(equal = 12))]
    a: String,
    #[modify(capitalize)]
    #[validate(length(equal = 14))]
    b: String,
}

fn do_something(input: &mut String) {
    *input = String::from("modified");
}

let mut test = Testor {
  a: "   LOWER ME     ".to_string(),
  b: Some("  makemeshout   ".to_string()),
  c: "I'll never be the same".to_string(),
  d: Some("Me neither".to_string()),
  nested: Nestor {
    a: "   notsotinynow   ".to_string(),
      b: "capitalize me.".to_string(),
  },
};

// The magic line
let res = Testor::validify(test.into());

assert!(matches!(res, Ok(_)));

let test = res.unwrap();

// Parent
assert_eq!(test.a, "lower me");
assert_eq!(test.b, Some("MAKEMESHOUT".to_string()));
assert_eq!(test.c, "modified");
assert_eq!(test.d, Some("modified".to_string()));
// Nested
assert_eq!(test.nested.a, "NOTSOTINYNOW");
assert_eq!(test.nested.b, "Capitalize me.");

Required Associated Types§

source

type Payload: DeserializeOwned + Validate

Represents the same structure of the implementing struct, with all its fields as options. Used to represent a completely deserializable version of the struct even if the fields are missing. Used for more detailed descriptions of what fields are missing, along with any other validation errors.

This type is automatically implemented when deriving validify by creating an accompanying payload struct:

#[derive(Debug, Clone, serde::Deserialize, Validify)]
struct Data {
    a: String,
    b: Option<String>
}

Expands to:

#[derive(Debug, Validate, serde::Deserialize)]
struct DataPayload {
    #[validate(required)]
    a: Option<String>,
    b: Option<String>
}

/*
 * serde impls and other stuff
 */

impl Validify for Data {
    type Payload = DataPayload;

    /* fn validify(payload: Self::Payload) { ... } */
}

Provided Methods§

source

fn validify(payload: Self::Payload) -> Result<Self, ValidationErrors>

Apply the provided modifiers to the payload and run validations, returning the original struct if all the validations pass.

source

fn validify_self(&mut self) -> Result<(), ValidationErrors>

Apply the provided modifiers to self and run validations.

Object Safety§

This trait is not object safe.

Implementors§