[−][src]Struct valid::Validated
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>
.
Actually there is a way to construct an instance of
Validated
without actually doing any validation: we can use theValidation::success
method (see unit tests on how it can be done) We need this method for custom implementations of theValidate
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]
Trait Implementations
impl<C, T> Clone for Validated<C, T> where
T: Clone,
[src]
T: Clone,
fn clone(&self) -> Self
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<C, T> Copy for Validated<C, T> where
T: Copy,
[src]
T: Copy,
impl<C, T> Debug for Validated<C, T> where
T: Debug,
[src]
T: Debug,
impl<C, T> Deref for Validated<C, T>
[src]
impl<C, T> Eq for Validated<C, T> where
T: Eq,
[src]
T: Eq,
impl<C, T> PartialEq<Validated<C, T>> for Validated<C, T> where
T: PartialEq,
[src]
T: PartialEq,
Auto Trait Implementations
impl<C, T> RefUnwindSafe for Validated<C, T> where
C: RefUnwindSafe,
T: RefUnwindSafe,
C: RefUnwindSafe,
T: RefUnwindSafe,
impl<C, T> Send for Validated<C, T> where
C: Send,
T: Send,
C: Send,
T: Send,
impl<C, T> Sync for Validated<C, T> where
C: Sync,
T: Sync,
C: Sync,
T: Sync,
impl<C, T> Unpin for Validated<C, T> where
C: Unpin,
T: Unpin,
C: Unpin,
T: Unpin,
impl<C, T> UnwindSafe for Validated<C, T> where
C: UnwindSafe,
T: UnwindSafe,
C: UnwindSafe,
T: UnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,