use batch_impl::{batch_impl, batch_impl_only, batch_trait};
use std::rc::Rc;
trait BlanketAt0 {
fn tag(&self) -> u32;
}
#[batch_impl_only(u32 { fn tag(&self) -> u32 { 7 } })]
trait BlanketAt0 {}
#[batch_impl_only(#blanket(@all_methods){Box<@0>})]
trait BlanketAt0 {
fn tag(&self) -> u32;
}
#[test]
fn blanket_at0_position() {
let b = Box::new(5u32);
assert_eq!(<Box<u32> as BlanketAt0>::tag(&b), 7);
}
struct MyPtrWithNum<T, const N: usize>(Box<T>, [u8; N]);
impl<T, const N: usize> std::ops::Deref for MyPtrWithNum<T, N> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
trait CfgT {
fn tag(&self) -> u32;
}
#[batch_impl_only(u32 { fn tag(&self) -> u32 { 7 } })]
trait CfgT {}
#[batch_impl_only(<const N: usize> #blanket(@all){MyPtrWithNum<@0, N>})]
trait CfgT {
fn tag(&self) -> u32;
}
#[test]
fn blanket_at0_const_generic() {
let p = MyPtrWithNum(Box::new(5u32), [0u8; 4]);
assert_eq!(<MyPtrWithNum<u32, 4> as CfgT>::tag(&p), 7);
}
#[batch_impl(u32 { fn name(&self) -> String { self.to_string() } })]
#[batch_impl(#blanket(@all){&,Box,Rc})]
trait BlanketName {
fn name(&self) -> String;
}
#[batch_impl(u16 { fn inc(&mut self) -> u16 { *self += 1; *self } })]
#[batch_impl(#blanket(inc){&mut})]
trait BlanketInc {
fn inc(&mut self) -> u16;
}
#[batch_impl(u32 { fn deep(&self) -> u32 { *self } })]
#[batch_impl(#blanket(deep){Box^Rc:2, Box^Box^Box:3})]
trait BlanketDeep {
fn deep(&self) -> u32;
}
#[test]
fn blanket_delegate() {
let v = 42u32;
assert_eq!(v.name(), "42");
assert_eq!(Box::new(7u32).name(), "7");
assert_eq!(Rc::new(9u32).name(), "9");
let mut b = Box::new(2u16);
b.inc(); assert_eq!(*b, 3);
let mut x = 2u16;
let mut xr: &mut u16 = &mut x;
BlanketInc::inc(&mut xr); assert_eq!(x, 3);
let br: Box<Rc<u32>> = Box::new(Rc::new(1u32));
assert_eq!(br.deep(), 1);
let bbb: Box<Box<Box<u32>>> = Box::new(Box::new(Box::new(2u32)));
assert_eq!(bbb.deep(), 2);
}
trait LazyA {}
trait LazyB {}
batch_trait!(
@lazy_nums=[u8, u16];
@lazy_wrapped=[Box, Rc]^@lazy_nums;
@lazy_chain=@lazy_wrapped;
LazyA: @lazy_chain;
LazyB: @lazy_nums;
);
#[batch_impl(Foo<u32> u32 {
type Item = u8;
const LIMIT: usize = 42;
fn m(&self) -> u32 { *self }
})]
#[batch_impl(#blanket(@all){&})]
trait Foo<X: Clone>
where
X: Send,
{
type Item;
const LIMIT: usize;
fn m(&self) -> X;
}
#[test]
fn lazy_const_and_generic_blanket() {
fn _a<T: LazyA>(_: &T) {}
_a(&Box::new(0u8));
_a(&Rc::new(0u16));
fn _b<T: LazyB>(_: &T) {}
_b(&0u8);
_b(&0u16);
assert_eq!(<u32 as Foo<u32>>::m(&5u32), 5);
assert_eq!(<&u32 as Foo<u32>>::m(&&5u32), 5); assert_eq!(<&u32 as Foo<u32>>::LIMIT, 42); let _: <&u32 as Foo<u32>>::Item = 8u8; }
#[batch_impl(#blanket(@all_methods){Box})]
trait ConsumeAll {
fn consume(self);
fn len(&self) -> usize;
}
impl ConsumeAll for u8 {
fn consume(self) {}
fn len(&self) -> usize {
1
}
}
#[test]
fn blanket_by_value_receiver() {
fn _c<T: ConsumeAll>(_: &T) {}
_c(&Box::new(0u8));
assert_eq!(Box::new(7u8).len(), 1);
Box::new(9u8).consume(); }
#[batch_impl(#[allow(dead_code)] Box^u8)]
trait AttrChain {}
#[test]
fn attr_wrapper_chain() {
fn _c<T: AttrChain>(_: &T) {}
_c(&Box::new(0u8));
}