[][src]Struct valid::Validated

pub struct Validated<C, T>(_, _);

A wrapper type to express that the value of type T has been validated by the constraint C.

The idea is that an instance of Validated<C, T> can only be obtained by validating a value of type T using the constraint C. There is no way to construct an instance of Validated directly.1

It follows the new type pattern and can be de-referenced to a immutable reference to its inner value or unwrapped to get the owned inner value.

In an application we can make use of the type system to assure that only valid values of some type can be input to some function performing some domain related things.

For example, lets assume we have a function that expects a valid email address as input. We could write the function like:

fn send_email(to: String, message: String) {
    unimplemented!()
}

The problem with this approach is, that we can never be sure that the string input for the to argument is a valid email address.

Lets rewrite the same function using Validated<Email, String>.

use valid::Validated;

fn send_email(to: Validated<Email, String>, message: String) {
    unimplemented!()
}

Due to we can not instantiate Validated directly using some constructor function like Validated(email) or Validated::new(email) we need to use a validation function like:

# fn send_email(to: Validated<Email, String>, message: String) {
#     unimplemented!()
# }
use valid::{Validated, Validate};

let to_addr = "jane.doe@email.net".to_string().validate("email", Email).result()
        .expect("valid email address");

send_email(to_addr, "some message".into());

Now we can be sure that the variable to_addr contains a valid email address.

To further make use of meaningful new types we might define a custom new type for email addresses, that can only be constructed from a validated value like so:

# fn send_email(to: EmailAddress, message: String) {
#     unimplemented!()
# }
use valid::{Validate, Validated};

mod domain_model {
    use valid::Validated;
    pub struct EmailAddress(String);

    impl From<Validated<Email, String>> for EmailAddress {
        fn from(value: Validated<String>) -> Self {
            EmailAddress(value.unwrap())
        }
    }
}

let validated = "jane.doe@email.net".to_string().validate("email", Email).result(None)
        .expect("valid email address");

let to_addr = EmailAddress::from(validated);

send_email(to_addr, "some message".into());

Due to the type EmailAddress is defined in another module it can only be constructed from a Validated<Email, String>.


  1. Actually there is a way to construct an instance of Validated without actually doing any validation: we can use the Validation::success method (see unit tests on how it can be done) We need this method for custom implementations of the Validate trait. Unfortunately I have no idea how to prevent this. Fortunately such code can be found by (automated) code review. 

Implementations

impl<C, T> Validated<C, T>[src]

pub fn unwrap(self) -> T[src]

Unwraps the original value that has been validated

Trait Implementations

impl<C, T> Clone for Validated<C, T> where
    T: Clone
[src]

impl<C, T> Copy for Validated<C, T> where
    T: Copy
[src]

impl<C, T> Debug for Validated<C, T> where
    T: Debug
[src]

impl<C, T> Deref for Validated<C, T>[src]

type Target = T

The resulting type after dereferencing.

impl<C, T> Eq for Validated<C, T> where
    T: Eq
[src]

impl<C, T> PartialEq<Validated<C, T>> for Validated<C, T> where
    T: PartialEq
[src]

Auto Trait Implementations

impl<C, T> RefUnwindSafe for Validated<C, T> where
    C: RefUnwindSafe,
    T: RefUnwindSafe

impl<C, T> Send for Validated<C, T> where
    C: Send,
    T: Send

impl<C, T> Sync for Validated<C, T> where
    C: Sync,
    T: Sync

impl<C, T> Unpin for Validated<C, T> where
    C: Unpin,
    T: Unpin

impl<C, T> UnwindSafe for Validated<C, T> where
    C: UnwindSafe,
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.