#extension #trait

macro dev extend

Create extensions for types you don’t own with extension traits but without the boilerplate

5 releases

✓ Uses Rust 2018 edition

new 0.1.2 May 22, 2020
0.1.1 Feb 22, 2020
0.1.0 Nov 26, 2019
0.0.2 Oct 30, 2019
0.0.1 Oct 30, 2019

#93 in Rust patterns

Download history 2/week @ 2020-02-06 186/week @ 2020-02-13 2996/week @ 2020-02-20 2915/week @ 2020-02-27 3375/week @ 2020-03-05 3705/week @ 2020-03-12 3695/week @ 2020-03-19 3491/week @ 2020-03-26 3921/week @ 2020-04-02 3668/week @ 2020-04-09 4533/week @ 2020-04-16 5144/week @ 2020-04-23 5202/week @ 2020-04-30 4920/week @ 2020-05-07 4171/week @ 2020-05-14 3442/week @ 2020-05-21

17,254 downloads per month
Used in 75 crates (via assert-json-diff)

MIT license

16KB
287 lines

extend

Create extensions for types you don't own with extension traits but without the boilerplate.

Example:

use extend::ext;

#[ext]
impl<T: Ord> Vec<T> {
    fn sorted(mut self) -> Self {
        self.sort();
        self
    }
}

fn main() {
    assert_eq!(
        vec![1, 2, 3],
        vec![2, 3, 1].sorted(),
    );
}

How does it work?

Under the hood it generates a trait with methods in your impl and implements those for the type you specify. The code shown above expands roughly to:

trait VecExt<T: Ord> {
    fn sorted(mut self) -> Self;
}

impl<T: Ord> VecExt<T> for Vec<T> {
    fn sorted(mut self) -> Self {
        self.sort();
        self
    }
}

Configuration

You can configure:

  • The visibility of the trait. The default visibility is private. Example: #[ext(pub)]. This must be the first argument to the attribute
  • The name of the generated extension trait. Example: #[ext(name = MyExt)].
  • Whether or not the generated trait should be sealed. Example: #[ext(sealed = false)]. The default is true.

More examples:

use extend::ext;

#[ext(name = SortedVecExt)]
impl<T: Ord> Vec<T> {
    fn sorted(mut self) -> Self {
        self.sort();
        self
    }
}

#[ext(pub(crate))]
impl i32 {
    fn double(self) -> i32 {
        self * 2
    }
}

#[ext(pub, name = ResultSafeUnwrapExt)]
impl<T> Result<T, std::convert::Infallible> {
    fn safe_unwrap(self) -> T {
        match self {
            Ok(t) => t,
            Err(_) => unreachable!(),
        }
    }
}

License: MIT

Dependencies

~0.5–0.8MB
~18K SLoC