Support Ukraine. DONATE.
A blog about software development.

Nutype 0.6.2 – Deriving Arbitrary Traits with `derive_unsafe`

Serhii Potapov July 30, 2025 #rust #macro #newtype #nutype #error

I'm excited to announce the release of Nutype v0.6.2! This update brings several valuable improvements, including a powerful (but potentially risky) new feature for trait derivation. You can find the full release notes on GitHub.

What is Nutype?

Nutype is a Rust crate that enhances the newtype pattern with built-in validation and sanitization using procedural macros.

It ensures that values conform to defined constraints at the time of instantiation, making your domain types safer and more robust—especially when dealing with untrusted data (e.g., user input or deserialized content).


Deriving Arbitrary Traits

Until now, trait derivation in Nutype was done using the derive(..) attribute inside the #[nutype(..)] macro:

#[nutype(derive(Debug))]
pub struct Username(String);

This approach is still recommended, as Nutype guarantees that the derived traits won't violate the type's invariants (e.g., by exposing the inner value inappropriately).

However, this method supports only a predefined, whitelisted set of traits. You couldn't derive arbitrary third-party traits—until now.

derive_unsafe(..): More Power, More Responsibility

Starting in v0.6.2, you can now use the new derive_unsafe(..) attribute to derive any trait, including those from external crates. This feature is opt-in and requires the derive_unsafe feature flag to be enabled.

Here's a practical (and dangerous) example:

use derive_more::{Deref, DerefMut};
use nutype::nutype;

#[nutype(
    derive(Debug, AsRef),
    derive_unsafe(Deref, DerefMut),
    validate(greater_or_equal = 0.0, less_or_equal = 2.0)
)]
struct LlmTemperature(f64);

fn main() {
    let mut temperature = LlmTemperature::try_new(1.5).unwrap();

    // ⚠️ This mutates the inner value directly, bypassing validation!
    *temperature = 2.5;

    // Invariant broken: 2.5 is outside the allowed range
    assert_eq!(temperature.as_ref(), &2.5);
}

IMPORTANT: Nutype cannot validate that the derived trait won't compromise your type's invariants. It's your responsibility as a developer to use it wisely. Think of it like Rust’s unsafe: powerful, but only safe when used correctly.