Name Description Size
lib.rs Create extensions for types you don't own with [extension traits] but without the boilerplate. Example: ```rust use extend::ext; #[ext] impl<T: Ord> Vec<T> { fn sorted(mut self) -> Self { self.sort(); self } } 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: ```rust trait VecExt<T: Ord> { fn sorted(self) -> Self; } impl<T: Ord> VecExt<T> for Vec<T> { fn sorted(mut self) -> Self { self.sort(); self } } ``` # Supported items Extensions can contain methods or associated constants: ```rust use extend::ext; #[ext] impl String { const CONSTANT: &'static str = "FOO"; fn method() { // ... # todo!() } } ``` # Configuration You can configure: - The visibility of the trait. Use `pub impl ...` to generate `pub trait ...`. The default visibility is private. - The name of the generated extension trait. Example: `#[ext(name = MyExt)]`. By default we generate a name based on what you extend. - Which supertraits the generated extension trait should have. Default is no supertraits. Example: `#[ext(supertraits = Default + Clone)]`. More examples: ```rust 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(name = ResultSafeUnwrapExt)] pub impl<T> Result<T, std::convert::Infallible> { fn safe_unwrap(self) -> T { match self { Ok(t) => t, Err(_) => unreachable!(), } } } #[ext(supertraits = Default + Clone)] impl String { fn my_length(self) -> usize { self.len() } } ``` For backwards compatibility you can also declare the visibility as the first argument to `#[ext]`: ``` use extend::ext; #[ext(pub)] impl i32 { fn double(self) -> i32 { self * 2 } } ``` # async-trait compatibility Async extensions are supported via [async-trait](https://crates.io/crates/async-trait). Be aware that you need to add `#[async_trait]` _below_ `#[ext]`. Otherwise the `ext` macro cannot see the `#[async_trait]` attribute and pass it along in the generated code. Example: ``` use extend::ext; use async_trait::async_trait; #[ext] #[async_trait] impl String { async fn read_file() -> String { // ... # todo!() } } ``` # Other attributes Other attributes provided _below_ `#[ext]` will be passed along to both the generated trait and the implementation. See [async-trait compatibility](#async-trait-compatibility) above for an example. [extension traits]: https://dev.to/matsimitsu/extending-existing-functionality-in-rust-with-traits-in-rust-3622 19502