← ClaudeAtlas

rust-newtype-and-raiilisted

Wrap a value in a newtype to enforce an invariant or prevent argument mix-ups, or use Drop to guarantee cleanup / enforce that an API is finalized correctly. Use when designing a type that must always be valid once constructed, when a resource (lock, file, transaction, connection) must always be released or finalized, or when reviewing whether a Drop-based guarantee actually holds.
takurot/rust-skills-comprehensive · ★ 0 · AI & Automation · score 71
Install: claude install-skill takurot/rust-skills-comprehensive
# Rust Newtype Pattern & RAII `rust-patterns` mentions the newtype pattern in passing (~18 lines) for type-safety and has no RAII section. This skill is for actually **designing** a newtype whose invariant needs to be airtight, or a `Drop`-based guarantee (a lock, a transaction, a temp file) that must hold even under panics and early returns. ## Newtype pattern ### Problem 1: semantic confusion between same-typed arguments ```rust // Both &str — the compiler can't stop you from swapping them at a call site. fn login(username: &str, password: &str) -> Result<(), LoginError> { ... } login(password, username); // compiles, silently wrong — bug or vulnerability ``` Wrapping each in a distinct newtype makes the swap a compile error instead of a runtime bug: ```rust struct Username(String); struct Password(String); fn login(username: &Username, password: &Password) -> Result<(), LoginError> { ... } login(password, username); // ❌ won't compile ``` Use this whenever a function takes two-or-more arguments of the *same underlying type* that are not interchangeable — IDs, coordinates in different units, currency amounts in different currencies, distinct kinds of strings. ### Problem 2: enforcing an invariant at construction ("parse, don't validate") A newtype plus a private field plus a fallible constructor makes "every value of this type is valid" a property the compiler helps hold, not just documentation: ```rust pub struct Username(String); // field is NOT pub impl Us