From 0ffcad9bcc588b7897d7521d5de7ee24a9adf4f5 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Thu, 17 Nov 2022 12:27:51 +0000 Subject: [PATCH] Better doc for newtype wrappers --- README.md | 42 ++++++++++++++++++++++++++++++------------ tests/newtype.rs | 2 ++ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b1f1326..0e7906d 100644 --- a/README.md +++ b/README.md @@ -30,17 +30,16 @@ Unlike [alternatives](#alternatives), `#[autoimpl]` has minimal and intuitive sy use impl_tools::autoimpl; use std::fmt::Debug; -#[autoimpl(for<'a, T: trait + ?Sized> Box)] -// Generates: impl<'a, T: Animal + ?Sized> Animal for Box { .. } +// Impl Animal for Box where T: Animal + ?Sized +#[autoimpl(for Box)] trait Animal { fn number_of_legs(&self) -> u32; } +// Impl Debug for Named omitting field animal from output #[autoimpl(Debug ignore self.animal where T: Debug)] -// Generates: impl std::fmt::Debug for Named where T: Debug { .. } +// Impl Deref and DerefMut to field animal for Named #[autoimpl(Deref, DerefMut using self.animal)] -// Generates: impl std::ops::Deref for Named { .. } -// Generates: impl std::ops::DerefMut for Named { .. } struct Named { name: T, animal: A, @@ -73,20 +72,39 @@ trait allows succinct new-type patterns: ```rust use impl_tools::autoimpl; +use std::sync::Arc; -#[autoimpl(for &T, &mut T)] -trait Foo { +// Impl Foo for &T, &mut T and Arc +#[autoimpl(for &T, &mut T, Arc)] +// Optional: impl Foo for NewFoo (requires NewFoo: Deref) +#[autoimpl(for NewFoo)] +pub trait Foo { fn success(&self) -> bool; } -#[autoimpl(Deref, DerefMut using self.0)] -struct NewFoo(T); +// Impl Deref and DerefMut to a Target which itself supports Foo +#[autoimpl(Deref, DerefMut using self.0)] +pub struct NewFoo(T); + +// Impl Deref and DerefMut to a Target which itself supports Foo +#[autoimpl(Deref, DerefMut using self.0)] +pub struct ArcDynFoo(Arc); + +#[test] +fn test_foo_newtypes() { + struct Success; + impl Foo for Success { + fn success(&self) -> bool { true } + } -// NewFoo now supports `Deref` and `&T` supports `Foo`. -// Effectively, `NewFoo` supports `Foo`. -// Works for FooRef<'a>(&'a dyn Foo) too; see tests/newtype.rs + // We can now directly call Foo's methods on the wrapper: + assert!(NewFoo(Success).success()); + assert!(ArcDynFoo(Arc::new(Success)).success()); +} ``` +See [`tests/newtype.rs`](https://github.com/kas-gui/impl-tools/blob/master/tests/newtype.rs) for more variants of this pattern. + ### Impl Default diff --git a/tests/newtype.rs b/tests/newtype.rs index 9ef2792..f3300c3 100644 --- a/tests/newtype.rs +++ b/tests/newtype.rs @@ -8,6 +8,8 @@ mod inner { use impl_tools::autoimpl; #[autoimpl(for &T, &mut T, Box, Rc, Arc)] + // Optionally, we can also implement Foo directly for these types: + // #[autoimpl(for NewFoo, BoxFoo)] pub trait Foo { fn is_true(&self) -> bool; }