Skip to content

Commit 29fbb00

Browse files
authored
Merge pull request #6 from KodrAus/feat/by-value-and-static-methods
Support by-value and static methods where possible
2 parents 53a2e89 + ae5056a commit 29fbb00

File tree

7 files changed

+382
-158
lines changed

7 files changed

+382
-158
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "auto_impl"
3-
version = "0.1.2"
3+
version = "0.2.0"
44
authors = ["Ashley Mannix <[email protected]>"]
55
license = "MIT"
66
description = "Automatically implement traits for common smart pointers and closures"

README.md

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,39 @@ extern crate auto_impl;
2222
use auto_impl::auto_impl;
2323
```
2424

25-
The following types are supported:
25+
Add an `auto_impl` attribute to traits you want to automatically implement for wrapper types:
26+
27+
```rust
28+
#[auto_impl(&, Arc)]
29+
pub trait OrderStoreFilter {
30+
fn filter<F>(&self, predicate: F) -> Result<Iter, Error>
31+
where
32+
F: Fn(&OrderData) -> bool;
33+
}
34+
```
35+
36+
Now anywhere that requires a `T: OrderStoreFilter` will also accept an `&T` or `Arc<T>` where `T` implements `OrderStoreFilter`.
37+
38+
## Specifics
39+
40+
The following types are supported and can be freely combined:
2641

2742
- [`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)
2843
- [`Rc`](https://doc.rust-lang.org/std/rc/struct.Rc.html)
2944
- [`Box`](https://doc.rust-lang.org/std/boxed/struct.Box.html)
45+
46+
The following types are also supported, but require a blanket implementation (you can only have one of these per `trait`):
47+
3048
- [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn.html)
3149
- [`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html)
3250
- [`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html)
3351
- `&`
3452
- `&mut`
3553

36-
## Implement a trait for a smart pointer
37-
38-
Add the `#[auto_impl]` attribute to traits to automatically implement them for wrapper types:
54+
## Implement a trait for `Box`
3955

4056
```rust
41-
#[auto_impl(Arc, Box, Rc)]
57+
#[auto_impl(Box)]
4258
trait MyTrait<'a, T>
4359
where T: AsRef<str>
4460
{
@@ -47,41 +63,74 @@ trait MyTrait<'a, T>
4763

4864
fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String>;
4965
fn execute2(&self) -> Self::Type2;
66+
fn execute3(self) -> Self::Type1;
67+
fn execute4() -> &'static str;
5068
}
5169
```
5270

5371
Will expand to:
5472

5573
```rust
56-
impl<'a, T, TAutoImpl> MyTrait<'a, T> for ::std::sync::Arc<TAutoImpl>
74+
impl<'a, T, TAutoImpl> MyTrait<'a, T> for ::std::boxed::Box<TAutoImpl>
5775
where TAutoImpl: MyTrait<'a, T>,
5876
T: AsRef<str>
5977
{
6078
type Type1 = TAutoImpl::Type1;
6179
type Type2 = TAutoImpl::Type2;
6280

6381
fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String> {
64-
self.as_ref().execute1(arg1)
82+
(**self).execute1(arg1)
6583
}
6684

6785
fn execute2(&self) -> Self::Type2 {
68-
self.as_ref().execute2()
86+
(**self).execute2()
87+
}
88+
89+
fn execute3(self) -> Self::Type1 {
90+
(*self).execute3()
6991
}
92+
93+
fn execute4() -> &'static str {
94+
TAutoImpl::execute4()
95+
}
96+
}
97+
```
98+
99+
There are no restrictions on `auto_impl` for `Box`.
100+
101+
## Implement a trait for a smart pointer
102+
103+
Add the `#[auto_impl]` attribute to traits to automatically implement them for wrapper types:
104+
105+
```rust
106+
#[auto_impl(Arc, Rc)]
107+
trait MyTrait<'a, T>
108+
where T: AsRef<str>
109+
{
110+
type Type1;
111+
type Type2;
112+
113+
fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String>;
114+
fn execute2(&self) -> Self::Type2;
70115
}
116+
```
71117

72-
impl<'a, T, TAutoImpl> MyTrait<'a, T> for Box<TAutoImpl>
118+
Will expand to:
119+
120+
```rust
121+
impl<'a, T, TAutoImpl> MyTrait<'a, T> for ::std::sync::Arc<TAutoImpl>
73122
where TAutoImpl: MyTrait<'a, T>,
74123
T: AsRef<str>
75124
{
76125
type Type1 = TAutoImpl::Type1;
77126
type Type2 = TAutoImpl::Type2;
78127

79128
fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String> {
80-
self.as_ref().execute1(arg1)
129+
(**self).execute1(arg1)
81130
}
82131

83132
fn execute2(&self) -> Self::Type2 {
84-
self.as_ref().execute2()
133+
(**self).execute2()
85134
}
86135
}
87136

@@ -93,18 +142,18 @@ impl<'a, T, TAutoImpl> MyTrait<'a, T> for ::std::rc::Rc<TAutoImpl>
93142
type Type2 = TAutoImpl::Type2;
94143

95144
fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String> {
96-
self.as_ref().execute1(arg1)
145+
(**self).execute1(arg1)
97146
}
98147

99148
fn execute2(&self) -> Self::Type2 {
100-
self.as_ref().execute2()
149+
(**self).execute2()
101150
}
102151
}
103152
```
104153

105154
There are a few restrictions on `#[auto_impl]` for smart pointers. The trait must:
106155

107-
- Only have methods that take `&self`
156+
- Only have methods that take `&self` or have no receiver (static)
108157

109158
## Implement a trait for a closure
110159

@@ -119,7 +168,7 @@ Will expand to:
119168

120169
```rust
121170
impl<'a, T, TAutoImpl> MyTrait<'a, T> for TAutoImpl
122-
where TAutoImpl: Fn(&T, &'static str) -> Result<(), String>
171+
where TAutoImpl: ::std::ops::Fn(&T, &'static str) -> Result<(), String>
123172
{
124173
fn execute<'b>(&'a self, arg1: &'b T, arg1: &'static str) -> Result<(), String> {
125174
self(arg1, arg2)
@@ -160,6 +209,8 @@ impl<'auto, 'a, T, TAutoImpl> MyTrait<'a, T> for &'auto mut TAutoImpl {
160209

161210
There are a few restrictions on `#[auto_impl]` for immutably borrowed references. The trait must:
162211

163-
- Only have methods that take `&self`
212+
- Only have methods that take `&self` or have no receiver (static)
213+
214+
There are a few restrictions on `#[auto_impl]` for mutably borrowed references. The trait must:
164215

165-
There are no restrictions on `#[auto_impl]` for mutably borrowed references.
216+
- Only have methods that take `&self`, `&mut self` or have no receiver (static)

compile_test/src/main.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/*!
2+
Try running `cargo expand` on this crate to see the output of `#[auto_impl]`.
3+
*/
4+
15
#![feature(proc_macro)]
26

37
extern crate auto_impl;
@@ -28,6 +32,17 @@ trait RefTrait1<'a, T: for<'b> Into<&'b str>> {
2832
fn execute2(&self) -> Self::Type2;
2933
}
3034

35+
#[auto_impl(Box)]
36+
trait BoxTrait1<'a, T: for<'b> Into<&'b str>> {
37+
type Type1;
38+
type Type2;
39+
40+
fn execute1<'b>(&'a self, arg1: &'b T) -> Result<Self::Type1, String>;
41+
fn execute2(&mut self, arg1: i32) -> Self::Type2;
42+
fn execute3(self) -> Self::Type1;
43+
fn execute4(arg1: String) -> Result<i32, String>;
44+
}
45+
3146
fn main() {
3247
println!("Hello, world!");
3348
}

0 commit comments

Comments
 (0)