#traits #newtype #attribute-macro #proc-macro

newer-type

Support defining newtype wrapper with inheriting trait implementations

1 unstable release

new 0.1.0 Mar 27, 2025

#1024 in Rust patterns

MIT license

19KB
286 lines

newer-type crate Latest Version Documentation GitHub Actions

Ergonomic support for the newtype pattern in Rust, with automatic trait implementations.

The newtype pattern in Rust is useful for creating distinct types without runtime overhead. However, it often requires boilerplate code to re-implement traits of the inner type.

The newer-type crate provides a procedural macro #[implement(...)] to reduce that boilerplate by automatically implementing traits for your wrapper types.

Features

The #[implement(...)] macro currently supports automatic implementations for:

  • User-defined traits annotated with #[target]
  • Some common traits from std, see newer_type::traits

Example

Without newer-type (manual newtype definition)

trait SayHello {
    fn say_hello(&self) -> String;
}

impl SayHello for String {
    fn say_hello(&self) -> String {
        format!("Hello, {}!", self)
    }
}

pub struct MyName(String);

impl SayHello for MyName {
    fn say_hello(&self) -> String {
        self.0.say_hello()
    }
}

With newer-type crate

# use newer_type::{implement, target};
#[target]
trait SayHello {
    fn say_hello(&self) -> String;
}

impl SayHello for String {
    fn say_hello(&self) -> String {
        format!("Hello, {}!", self)
    }
}

#[implement(SayHello)]
pub struct MyName(String);

That's it! The selected traits are automatically implemented for you.

Examples using newer_type::traits

In order to implement traits defined in Rust's standard library for your newtype, there are empty definitions in newer_type::traits namespace. You can pick up traits to be implemented from it.

# use newer_type::implement;
use newer_type::traits::{IntoIterator, Extend, PartialEq, Eq};

#[implement(IntoIterator, Extend<T>, PartialEq, Eq)]
struct MyVec<T>(Vec<T>);

// now `MyVec` implements std::iter::IntoIterator, std::ops::Extend, std::cmp::{PartialEq, Eq}

Use Cases

This crate is particularly useful when:

  • You want to create safe wrappers for existing types (e.g. for validation or domain modeling)
  • You're working with abstract data structures like ASTs or instruction sets and want ergonomic iteration
  • You frequently use the newtype pattern and want to avoid repetitive code

Installation

Add this to your Cargo.toml:

[dependencies]
newer-type = "0.1"

License

MIT

Dependencies

~2.8–4.5MB
~87K SLoC