Structs
Parse vs validate
When to parse input into a struct and when to validate an existing value, and which field names each one uses.
Structs from schema! and #[derive(Validate)] can be checked in two directions.
parse / parse_value / vld_parse | validate / is_valid | |
|---|---|---|
| Input | JSON (string, bytes, file, Value) | an existing Rust value that implements Serialize |
| Output | a new struct, with transforms and defaults applied | Ok(()) or Err(VldError) |
| Field names | deserialize names | serialize names |
| Typical use | request bodies, config files, messages | data built in code, before saving or sending |
use vld::prelude::*;
vld::schema! {
#[derive(Debug, serde::Serialize)]
pub struct Account {
pub email: String => vld::string().email(),
pub balance: f64 => vld::number().non_negative(),
}
}
// Incoming data:
let acc = Account::parse(r#"{"email": "ada@example.com", "balance": 10}"#).unwrap();
// Data changed in code:
let mut changed = acc;
changed.balance -= 25.0;
assert!(!Account::is_valid(&changed));
let err = Account::validate(&changed).unwrap_err();
assert_eq!(err.issues[0].code.key(), "too_small");
validate serializes the value with serde and runs the same field schemas. Because the value goes through Serialize, the serialize names apply. With different serialize and deserialize names (rename(serialize = "a", deserialize = "b") or rename_all(serialize = ..., deserialize = ...)) a value serialized by your struct still validates.
Any schema also has schema.validate(&value) and schema.is_valid(&value) for single values:
assert!(vld::string().email().is_valid(&"ada@example.com"));
assert!(vld::array(vld::u8()).validate(&vec![1, 2, 3]).is_ok());
impl_rules! adds validate() / is_valid() as instance methods to structs you did not declare with schema!: see impl_rules!.