Skip to content

Commit 0ffcad9

Browse files
committed
Better doc for newtype wrappers
1 parent 47f8907 commit 0ffcad9

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

README.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,16 @@ Unlike [alternatives](#alternatives), `#[autoimpl]` has minimal and intuitive sy
3030
use impl_tools::autoimpl;
3131
use std::fmt::Debug;
3232

33-
#[autoimpl(for<'a, T: trait + ?Sized> Box<T>)]
34-
// Generates: impl<'a, T: Animal + ?Sized> Animal for Box<T> { .. }
33+
// Impl Animal for Box<T> where T: Animal + ?Sized
34+
#[autoimpl(for<T: trait + ?Sized> Box<T>)]
3535
trait Animal {
3636
fn number_of_legs(&self) -> u32;
3737
}
3838

39+
// Impl Debug for Named<T, A: Animal> omitting field animal from output
3940
#[autoimpl(Debug ignore self.animal where T: Debug)]
40-
// Generates: impl<T, A: Animal> std::fmt::Debug for Named<A> where T: Debug { .. }
41+
// Impl Deref and DerefMut to field animal for Named<T, A: Animal>
4142
#[autoimpl(Deref, DerefMut using self.animal)]
42-
// Generates: impl<T, A: Animal> std::ops::Deref for Named<A> { .. }
43-
// Generates: impl<T, A: Animal> std::ops::DerefMut for Named<A> { .. }
4443
struct Named<T, A: Animal> {
4544
name: T,
4645
animal: A,
@@ -73,20 +72,39 @@ trait allows succinct new-type patterns:
7372

7473
```rust
7574
use impl_tools::autoimpl;
75+
use std::sync::Arc;
7676

77-
#[autoimpl(for<T: trait> &T, &mut T)]
78-
trait Foo {
77+
// Impl Foo for &T, &mut T and Arc<T>
78+
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Arc<T>)]
79+
// Optional: impl Foo for NewFoo (requires NewFoo: Deref<Target = T>)
80+
#[autoimpl(for<T: trait> NewFoo<T>)]
81+
pub trait Foo {
7982
fn success(&self) -> bool;
8083
}
8184

82-
#[autoimpl(Deref, DerefMut using self.0)]
83-
struct NewFoo<T: Foo>(T);
85+
// Impl Deref and DerefMut to a Target which itself supports Foo
86+
#[autoimpl(Deref<Target = T>, DerefMut using self.0)]
87+
pub struct NewFoo<T: Foo>(T);
88+
89+
// Impl Deref and DerefMut to a Target which itself supports Foo
90+
#[autoimpl(Deref<Target = dyn Foo>, DerefMut using self.0)]
91+
pub struct ArcDynFoo(Arc<dyn Foo>);
92+
93+
#[test]
94+
fn test_foo_newtypes() {
95+
struct Success;
96+
impl Foo for Success {
97+
fn success(&self) -> bool { true }
98+
}
8499

85-
// NewFoo now supports `Deref<Target = T>` and `&T` supports `Foo`.
86-
// Effectively, `NewFoo` supports `Foo`.
87-
// Works for FooRef<'a>(&'a dyn Foo) too; see tests/newtype.rs
100+
// We can now directly call Foo's methods on the wrapper:
101+
assert!(NewFoo(Success).success());
102+
assert!(ArcDynFoo(Arc::new(Success)).success());
103+
}
88104
```
89105

106+
See [`tests/newtype.rs`](https://github.com/kas-gui/impl-tools/blob/master/tests/newtype.rs) for more variants of this pattern.
107+
90108

91109
### Impl Default
92110

tests/newtype.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ mod inner {
88
use impl_tools::autoimpl;
99

1010
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>, Rc<T>, Arc<T>)]
11+
// Optionally, we can also implement Foo directly for these types:
12+
// #[autoimpl(for<T: trait> NewFoo<T>, BoxFoo<T>)]
1113
pub trait Foo {
1214
fn is_true(&self) -> bool;
1315
}

0 commit comments

Comments
 (0)