.. /index

Parse, Don't Validate

Parse, Don't Validate

"Parse, don't validate" is a design principle articulated by Alexis King in November 2019 that captures the difference between two approaches to data checking:

This is the philosophical foundation of type-driven-development and the principle that makes the newtype-pattern powerful.

In Rust

// Validating: the type system forgets what we learned
fn is_valid_email(s: &str) -> bool { s.contains('@') }

// Parsing: the type system remembers
pub struct Email(String);
impl Email {
    pub fn parse(raw: String) -> Result<Self, &'static str> {
        if raw.contains('@') { Ok(Email(raw)) } else { Err("invalid email") }
    }
}

With the parsing approach, any function accepting Email is guaranteed to receive a validated value. The check happens once, at the boundary, and the type carries the proof forward.

The boundary principle

Parse at system boundaries — user input, API responses, file reads, deserialization. Once data crosses the boundary into a refined type, internal code operates on types that are correct by construction. This eliminates:

Relationship to other patterns

See type-driven-development for the full methodology, and high-level-rust for the pragmatic framing — type-first domain modeling is the easiest of the seven techniques to pick up first, and the one that pays off even before you've earned ownership/borrow fluency.

Linked from

Sources