How to always validate a struct on creation?

Suppose we need to always validate a struct when it's created. For instance, suppose that age can only be positive. We can develop a factory method that verifies that age is poisitive, but it can be bypassed:

#[derive(Debug)]
struct Age {
    age: f32,
}

impl Age {
    fn age_from(age: f32) -> Option<Age> {
        if age > 0.0 {
            Some(Age { age })
        } else {
            None
        }
    }
}

fn main() {
    let age = Age::age_from(23.4);
    println!("Age {:?}", age);
    // but nothing prevents us from bypassing the factory method
    let another_age = Age { age: -2.8 };
    println!("Another age {:?}", another_age);
}

is there a way to ensure validation cannot be bypassed? TIA!

Define the struct in its own module and make the field private.

6 Likes

It seems to be bypassable only because the "bypassing" code is in the same module - the privacy boundary is the module, not the impl block as you might be expecting. By moving the struct and impl into its own module, this code breaks as expected - here's the playground proving this.

7 Likes