rust-serde
Rust Serde
A #[derive(Deserialize)] is a claim that anything it accepts is already valid
for the domain — the parse is the only place that claim is cheap to enforce.
Deserialization is a parse
The type you deserialize into is the type the rest of the program trusts, so it
is the last place validation is cheap. A Config that deserializes with a
String port and checks it in run() has moved the failure past every layer
that could have reported it usefully. What the validated type should be is
/type-driven-design; this skill owns the boundary that type crosses.
#[serde(try_from = "...")] is the mechanism
Deserialize into a raw shape, convert with TryFrom into the validated type,
and the conversion failure becomes a deserialization error — the read fails,
not the first use of the value. The error must implement std::error::Error.