typestar

Newtypes hold invariants in Rust

Wrap a primitive so an invalid value cannot be constructed at all.

#[derive(Debug, Clone, Copy, PartialEq)]
struct Accuracy(f64);

impl Accuracy {
    fn new(value: f64) -> Option<Accuracy> {
        if (0.0..=100.0).contains(&value) {
            Some(Accuracy(value))
        } else {
            None
        }
    }

    fn value(&self) -> f64 {
        self.0
    }
}

fn grade(a: Accuracy) -> &'static str {
    if a.value() >= 97.0 {
        "clean"
    } else {
        "keep practicing"
    }
}

fn main() {
    let ok = Accuracy::new(98.5).unwrap();
    println!("{:?} {}", ok, grade(ok));
    println!("{:?}", Accuracy::new(140.0));
}

How it works

  1. The field is private, so the constructor is the only door.
  2. new returns Option or Result when validation can fail.
  3. The type then proves the invariant everywhere it appears.

Keywords and builtins used here

The run, in numbers

Lines
30
Characters to type
466
Tokens
148
Three-star pace
110 tpm

At the three-star pace of 110 tokens a minute, this run takes about 81 seconds.

Type this snippet

Step 2 of 2 in API patterns, step 11 of 12 in Modules, tests & macros.

← Previous Next →