Eli Bendersky6 min readintermediate
Rusty thoughts on "Parse, don't validate"
Summary
This post reviews the "Parse, don't validate" pattern in Rust, advocating for using the type system to enforce data invariants at compile time rather than relying on runtime checks. It demonstrates how custom types like NonEmpty<T>, AbsPathBuf, and NonZero prevent invalid states, improving code clarity and safety.
- Use custom types (e.g., NonEmpty<T>) to encode invariants like "not empty" directly into the type system.
- Type refinement allows gradual validation, transforming generic data into more specific, validated types (e.g., PathBuf -> Utf8PathBuf -> AbsPathBuf).
- Rust's NonZero types prevent division by zero and enable Option optimizations by using zero as a sentinel.
- Serde deserialization exemplifies "parse, don't validate" by mapping JSON to types that enforce schema and value constraints.
Rust developers can leverage the type system to build more robust and maintainable applications by shifting validation from runtime checks to compile-time guarantees.
7/10
