use batch_impl::{batch_impl, batch_impl_only};
macro_rules! ty {
() => { Vec<u8> };
}
macro_rules! passthrough {
($($t:tt)*) => { $($t)* };
}
#[batch_impl(ty![])]
trait MacroBracketA {}
#[batch_impl(passthrough![Vec<u8>])]
trait MacroBracketB {}
#[batch_impl(Box<ty![]>)]
trait MacroBracketC {}
#[batch_impl(
<T> MacroBracketFnRet<T> Vec<T> where T: Fn() -> ty![]
{ fn ok(&self) -> bool { true } }
)]
trait MacroBracketFnRet<T> {
fn ok(&self) -> bool;
}
#[test]
fn macro_bracket_passthrough() {
fn a<T: MacroBracketA>(_: &T) {}
fn b<T: MacroBracketB>(_: &T) {}
fn c<T: MacroBracketC>(_: &T) {}
a(&vec![1u8]);
b(&vec![1u8]);
c(&Box::new(vec![1u8]));
let v: Vec<fn() -> Vec<u8>> = vec![|| vec![1u8]];
assert!(v.ok());
}
trait MacroBracketDirective {
fn len(&self) -> usize;
}
macro_rules! len_ty {
(#len{ $n:expr }) => {
u8
};
}
#[batch_impl_only(
usize #len{5},
len_ty![#len{5}] #len{6}
)]
trait MacroBracketDirective {
fn len(&self) -> usize;
}
#[test]
fn macro_bracket_directive_not_expanded() {
assert_eq!(0usize.len(), 5);
assert_eq!(0u8.len(), 6);
}
trait MacroBracketWhere<T> {
fn ok2(&self) -> bool;
}
macro_rules! m2 {
(where) => { Vec<u8> };
}
#[batch_impl_only(
<T> MacroBracketWhere<T> Vec<T> where T: Fn() -> m2![where]
{ fn ok2(&self) -> bool { true } }
)]
trait MacroBracketWhere<T> {
fn ok2(&self) -> bool;
}
#[test]
fn macro_bracket_where_not_processed() {
let v: Vec<fn() -> Vec<u8>> = vec![|| vec![1u8]];
assert!(v.ok2());
}
mod ext {
pub mod traits {
pub trait PathPrefixTrait {
fn tag(&self) -> &'static str;
}
pub trait PathPrefixGen<T> {
fn head(&self) -> T;
}
}
}
use ext::traits::{PathPrefixGen, PathPrefixTrait};
#[batch_impl_only(
#ext::traits::PathPrefixTrait: usize #tag{"usize"}, isize #tag{"isize"}
)]
trait PathPrefixTrait {
fn tag(&self) -> &'static str;
}
#[test]
fn cmp_path_prefix_directive() {
assert_eq!(0usize.tag(), "usize");
assert_eq!(0isize.tag(), "isize");
}
#[batch_impl_only(
#ext::traits::PathPrefixGen: <T: Clone> PathPrefixGen<T> Vec<T>
{ fn head(&self) -> T { self[0].clone() } }
)]
trait PathPrefixGen<T> {
fn head(&self) -> T;
}
#[test]
fn cmp_path_prefix_trait_generic() {
assert_eq!(vec![1i32].head(), 1);
assert_eq!(vec![String::from("x")].head(), "x");
}
#[batch_impl_only(
#ext::traits::PathPrefixTrait: u8 #tag{"u8"},
#blanket(@all){&, Box}
)]
trait PathPrefixTrait {
fn tag(&self) -> &'static str;
}
#[test]
fn cmp_path_prefix_blanket() {
assert_eq!(<&u8 as PathPrefixTrait>::tag(&&0u8), "u8");
assert_eq!(Box::new(1u8).tag(), "u8");
}