1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! The `impl{...}` shape templates (0.8.0) advanced tests: merged templates, body-type
//! rewrites, coexistence with trait generics / where, and `batch_impl_only`.
//! (split from the former single-file `tests/shape_template_impl.rs`)
use batch_impl::{batch_impl, batch_impl_only};
// ------------------------------------------------------------
// 6. Multiple `impl{...}` merged: distinct slots both bound
// ------------------------------------------------------------
#[batch_impl(Box<u32> impl{X<u32>} impl{Y<u32>} { fn mk(x: u32) -> X<u32> { X::new(x) } })]
trait ImplMerge {
fn mk(x: u32) -> Self;
}
#[test]
fn impl_multiple_templates_merge() {
assert_eq!(*<Box<u32> as ImplMerge>::mk(9), 9);
}
// ------------------------------------------------------------
// 7. Slot rewrite applies inside generic args of the body's type positions
// ------------------------------------------------------------
#[batch_impl(Vec<i16> impl{Container<T>} { fn head(&self) -> Option<T> { self.first().copied() } })]
trait ImplBodyType {
fn head(&self) -> Option<i16>;
}
#[test]
fn impl_body_type_rewrite() {
let v = vec![3i16];
assert_eq!(v.head(), Some(3));
}
// ------------------------------------------------------------
// 8. `impl{...}` with `where{...}` and trait generics coexisting
// ------------------------------------------------------------
#[batch_impl(<T: Clone> ImplWhereMix<T> Vec<T> impl{Container<U>} where{Vec<T>: Clone} { fn n(&self) -> usize { self.len() } })]
trait ImplWhereMix<T> {
fn n(&self) -> usize;
}
#[test]
fn impl_where_coexist() {
let v = vec![1u8, 2, 3];
assert_eq!(v.n(), 3);
}
// ------------------------------------------------------------
// 9. `batch_impl_only` (trait from outside) supports impl{...}
// ------------------------------------------------------------
trait Outside {
fn tag(&self) -> &'static str;
}
#[batch_impl_only(usize impl{Num} { fn tag(&self) -> &'static str { "usize" } })]
trait Outside {
fn tag(&self) -> &'static str;
}
#[test]
fn impl_impl_only() {
assert_eq!(0usize.tag(), "usize");
}