Lenient parsing
parse() fails as a whole. Sometimes you want the opposite: keep the fields that are valid, use defaults for the rest and show what went wrong, for example when loading a user-edited settings file.
Lenient parsing is available on:
schema_validated!structs,schema!structs plusimpl_validate_fields!,#[derive(Validate)]structs with#[vld(lenient)].
Every field type must implement Default and serde::Serialize.
validate_fields
validate_fields(input) checks each field on its own and returns Vec<FieldResult>:
use vld::prelude::*;
vld::schema_validated! {
#[derive(Debug, Default, serde::Serialize)]
pub struct Settings {
pub name: String => vld::string().min(2),
pub port: i64 => vld::number().int().min(1).max(65535),
pub theme: String => vld::enumeration(&["light", "dark"]).with_default("light".into()),
}
}
let fields = Settings::validate_fields(r#"{"name": "X", "port": 8080}"#).unwrap();
for f in &fields {
println!("{f}");
}
// ✖ name: String must be at least 2 characters (received: "X")
// ✔ port: 8080
// ✔ theme: "light"
FieldResult has name, input (the raw value) and result: Result<Value, VldError>, plus is_ok() / is_err().
parse_lenient
parse_lenient(input) always builds the struct: valid fields get their parsed value, invalid ones Default::default(). It returns ParseResult<T>:
let r = Settings::parse_lenient(r#"{"name": "X", "port": 0}"#).unwrap();
assert_eq!(r.error_count(), 2);
assert_eq!(r.value.port, 0); // Default
assert_eq!(r.value.theme, "light"); // schema default
for f in r.error_fields() {
eprintln!("{f}");
}
let settings = r.into_value();
ParseResult method | Returns |
|---|---|
value (field) / into_value() / into_parts() | the struct, or the struct and the field results |
fields() / field(name) | all field results / one by name |
valid_fields() / error_fields() | filtered field results |
is_valid() / has_errors() / valid_count() / error_count() | summary |
to_json_value() / to_json_string() / save_to_file(path) | serialize the struct (needs T: Serialize) |
Both functions still return Err when the input is not an object at all. A .catch(..) field never counts as an error: the fallback is a valid value.