Skip to content

Commit bd1d966

Browse files
authored
Merge pull request #9 from LukasKalbertodt/rewrite
Rewrite most of the crate with updated dependencies
2 parents 29fbb00 + 624076f commit bd1d966

File tree

13 files changed

+969
-1169
lines changed

13 files changed

+969
-1169
lines changed

Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[package]
22
name = "auto_impl"
33
version = "0.2.0"
4-
authors = ["Ashley Mannix <[email protected]>"]
4+
authors = [
5+
"Ashley Mannix <[email protected]>",
6+
"Lukas Kalbertodt <[email protected]>",
7+
]
58
license = "MIT"
69
description = "Automatically implement traits for common smart pointers and closures"
710
repository = "https://github.com/KodrAus/auto_impl"
@@ -17,5 +20,6 @@ travis-ci = { repository = "KodrAus/auto_impl" }
1720
proc-macro = true
1821

1922
[dependencies]
20-
quote = "~0.3"
21-
syn = { version = "~0.11", features = ["full"] }
23+
proc-macro2 = { version = "0.4.6", features = ["nightly"] }
24+
quote = "0.6.3"
25+
syn = { version = "0.14.4", features = ["full"] }

compile_test/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Try running `cargo expand` on this crate to see the output of `#[auto_impl]`.
33
*/
44

5-
#![feature(proc_macro)]
5+
#![feature(use_extern_macros)]
66

77
extern crate auto_impl;
88

examples/greet_closure.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#![feature(use_extern_macros)]
2+
3+
extern crate auto_impl;
4+
5+
use auto_impl::auto_impl;
6+
7+
8+
/// This simple trait can be implemented for `Fn` types, but not for `FnMut` or
9+
/// `FnOnce` types. The latter two types require a mutable reference to `self`
10+
/// or a `self` by value to be called, but `greet()` only has an immutable
11+
/// reference. Try creating an auto-impl for `FnMut`: you should get an error.
12+
///
13+
/// This attribute expands to the following impl (not exactly this code, but
14+
/// equivalent, slightly uglier code):
15+
///
16+
/// ```
17+
/// impl<F: Fn(&str)> Greeter for F {
18+
/// fn greet(&self, name: &str) {
19+
/// self(name)
20+
/// }
21+
/// }
22+
/// ```
23+
#[auto_impl(Fn)]
24+
trait Greeter {
25+
fn greet(&self, name: &str);
26+
}
27+
28+
29+
fn greet_people(greeter: impl Greeter) {
30+
greeter.greet("Anna");
31+
greeter.greet("Bob");
32+
}
33+
34+
35+
fn main() {
36+
// We can simply pass a closure here, since this specific closure
37+
// implements `Fn(&str)` and therefore also `Greeter`. Note that we need
38+
// explicit type annotations here. This has nothing to do with `auto_impl`,
39+
// but is simply a limitation of type inference.
40+
greet_people(|name: &str| println!("Hallo {} :)", name));
41+
}

examples/refs.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#![feature(use_extern_macros)]
2+
3+
extern crate auto_impl;
4+
5+
use std::fmt::Display;
6+
7+
use auto_impl::auto_impl;
8+
9+
10+
/// This trait can be implemented for all reference or pointer types: &, &mut,
11+
/// Box, Rc and Arc.
12+
///
13+
/// This attribute expands to the following impl (not exactly this code, but
14+
/// equivalent, slightly uglier code):
15+
///
16+
/// ```
17+
/// impl<'a, T: 'a + DisplayCollection> DisplayCollection for &'a T {
18+
/// type Out = T::Out;
19+
/// fn display_at(&self, index: usize) -> Option<&Self::Out> {
20+
/// (**self).display_at(index)
21+
/// }
22+
/// }
23+
///
24+
/// impl<T: DisplayCollection> DisplayCollection for Box<T> {
25+
/// type Out = T::Out;
26+
/// fn display_at(&self, index: usize) -> Option<&Self::Out> {
27+
/// (**self).display_at(index)
28+
/// }
29+
/// }
30+
/// ```
31+
#[auto_impl(&, Box)]
32+
trait DisplayCollection {
33+
/// If the length is statically known, this is `Some(len)`.
34+
const LEN: Option<usize>;
35+
type Out: Display;
36+
fn display_at(&self, index: usize) -> Option<&Self::Out>;
37+
}
38+
39+
impl<T: Display> DisplayCollection for Vec<T> {
40+
const LEN: Option<usize> = None;
41+
type Out = T;
42+
fn display_at(&self, index: usize) -> Option<&Self::Out> {
43+
self.get(index)
44+
}
45+
}
46+
47+
fn show_first(c: impl DisplayCollection) {
48+
match c.display_at(0) {
49+
Some(x) => println!("First: {}", x),
50+
None => println!("Nothing :/"),
51+
}
52+
}
53+
54+
55+
fn main() {
56+
let v = vec!["dog", "cat"];
57+
let boxed = Box::new(v.clone());
58+
59+
show_first(v.clone()); // Vec<&str> (our manual impl)
60+
show_first(&v); // &Vec<&str> (auto-impl)
61+
show_first(&&v); // &&Vec<&str> (works too, of course)
62+
show_first(boxed.clone()); // Box<Vec<&str>> (auto-impl)
63+
show_first(&boxed); // &Box<Vec<&str>>
64+
}

0 commit comments

Comments
 (0)