#[doc(hidden)]
pub extern crate syn;
pub use crate::match_set::{Fork, MatchSet};
pub use proc_macro_rules_macros::rules;
mod match_set;
#[cfg(test)]
mod tests {
use crate as proc_macro_rules;
use super::*;
#[test]
fn test_smoke() {
let tokens: proc_macro2::TokenStream = "hi (a b c) # [there] the - rest".parse().unwrap();
rules!(tokens => {
($finish:ident ($($found:ident)+) # [ $($inner:tt)? ] $($rest:expr)*) => {
assert_eq!(finish.to_string(), "hi");
assert_eq!(found.len(), 3);
assert!(inner.is_some());
assert_eq!(rest.len(), 1);
return;
}
});
panic!();
}
#[test]
fn test_empty() {
let tokens: proc_macro2::TokenStream = "".parse().unwrap();
rules!(tokens => {
() => {
return;
}
});
panic!();
}
#[test]
#[should_panic]
fn test_no_match() {
let tokens: proc_macro2::TokenStream = "foo".parse().unwrap();
rules!(tokens => {
(bar) => {}
});
}
#[test]
fn test_branches() {
fn apply(tokens: proc_macro2::TokenStream, expected_branch: usize) {
rules!(tokens => {
(foo) => {
if expected_branch == 0 {
return;
} else {
panic!("branch: 0, expected: {}", expected_branch);
}
}
($x:ident) => {
if expected_branch == 1 {
assert_eq!(x.to_string(), "bar");
return;
} else {
panic!("branch: 1, expected: {}", expected_branch);
}
}
($($x:ident)*) => {
if expected_branch == 2 {
assert_eq!(x.len(), 3);
assert_eq!(x[0].to_string(), "a");
assert_eq!(x[1].to_string(), "b");
assert_eq!(x[2].to_string(), "c");
return;
} else {
panic!("branch: 2, expected: {}", expected_branch);
}
}
});
panic!("Hit no branches, expected: {}", expected_branch);
}
apply("foo".parse().unwrap(), 0);
apply("bar".parse().unwrap(), 1);
apply("a b c".parse().unwrap(), 2);
}
#[test]
fn test_opt() {
fn apply(tokens: proc_macro2::TokenStream) {
rules!(tokens => {
(foo $(bar),? baz) => {
return;
}
});
panic!();
}
apply("foo baz".parse().unwrap());
apply("foo bar baz".parse().unwrap());
apply("foo bar, baz".parse().unwrap());
}
#[test]
fn test_plus() {
fn apply(tokens: proc_macro2::TokenStream) {
rules!(tokens => {
(foo $(bar),+ baz) => {
return;
}
});
panic!();
}
apply("foo bar baz".parse().unwrap());
apply("foo bar, baz".parse().unwrap());
apply("foo bar, bar baz".parse().unwrap());
apply("foo bar, bar, baz".parse().unwrap());
apply("foo bar, bar, bar baz".parse().unwrap());
apply("foo bar, bar, bar, baz".parse().unwrap());
}
#[test]
fn test_star() {
fn apply(tokens: proc_macro2::TokenStream) {
rules!(tokens => {
(foo $(bar),* baz) => {
return;
}
});
panic!();
}
apply("foo baz".parse().unwrap());
apply("foo bar baz".parse().unwrap());
apply("foo bar, baz".parse().unwrap());
apply("foo bar, bar baz".parse().unwrap());
apply("foo bar, bar, baz".parse().unwrap());
apply("foo bar, bar, bar baz".parse().unwrap());
apply("foo bar, bar, bar, baz".parse().unwrap());
}
}