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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
macro_rules! named {
($name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
fn $name(input: $crate::nom::types::CompleteStr) -> $crate::nom::IResult<$crate::nom::types::CompleteStr, $o> {
$submac!(input, $($args)*)
}
};
}
#[macro_export]
macro_rules! weedle {
($i:expr, $t:ty) => {
<$t as $crate::Parse>::parse($i)
};
}
macro_rules! re_capture_static (
($i:expr, $re:expr) => (
{
use $crate::nom::{Err,ErrorKind,IResult};
use $crate::nom::Slice;
regex!(RE, $re);
if let Some(c) = RE.captures(&$i) {
let v:Vec<_> = c.iter().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|m| $i.slice(m.start()..m.end())).collect();
let offset = {
let end = v.last().unwrap();
end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
};
Ok(($i.slice(offset..), v))
} else {
let res: IResult<_,_> = Err(Err::Error(error_position!($i, ErrorKind::RegexpCapture::<u32>)));
res
}
}
)
);
#[macro_export]
macro_rules! opt_flat(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::nom::Err;
let i_ = $i.clone();
match $submac!(i_, $($args)*) {
Ok((i,o)) => Ok((i, o)),
Err(Err::Error(_)) => Ok(($i, None)),
Err(e) => Err(e),
}
}
);
);
#[cfg(test)]
macro_rules! test {
(@arg $parsed:ident) => {};
(@arg $parsed:ident $($lhs:tt).+ == $rhs:expr; $($rest:tt)*) => {
assert_eq!($parsed.$($lhs).+, $rhs);
test!(@arg $parsed $($rest)*);
};
(@arg $parsed:ident $($lhs:tt).+(); $($rest:tt)*) => {
assert!($parsed.$($lhs).+());
test!(@arg $parsed $($rest)*);
};
(@arg $parsed:ident $($lhs:tt).+() == $rhs:expr; $($rest:tt)*) => {
assert_eq!($parsed.$($lhs).+(), $rhs);
test!(@arg $parsed $($rest)*);
};
(err $name:ident { $raw:expr => $typ:ty }) => {
#[test]
fn $name() {
<$typ>::parse($crate::nom::types::CompleteStr($raw)).unwrap_err();
}
};
($name:ident { $raw:expr => $rem:expr; $typ:ty => $val:expr }) => {
#[test]
fn $name() {
let (rem, parsed) = <$typ>::parse($crate::nom::types::CompleteStr($raw)).unwrap();
assert_eq!(rem, $crate::nom::types::CompleteStr($rem));
assert_eq!(parsed, $val);
}
};
($name:ident { $raw:expr => $rem:expr; $typ:ty; $($body:tt)* }) => {
#[test]
fn $name() {
let (_rem, _parsed) = <$typ>::parse($crate::nom::types::CompleteStr($raw)).unwrap();
assert_eq!(_rem, $crate::nom::types::CompleteStr($rem));
test!(@arg _parsed $($body)*);
}
};
}
#[macro_export]
macro_rules! test_variants {
($struct_:ident { $( $variant:ident == $value:expr ),* $(,)* }) => {
#[allow(non_snake_case)]
mod $struct_ {
$(
mod $variant {
use $crate::types::*;
use $crate::nom::types::CompleteStr;
#[test]
fn should_parse() {
let (rem, parsed) = $struct_::parse(CompleteStr($value)).unwrap();
assert_eq!(rem, CompleteStr(""));
match parsed {
$struct_::$variant(_) => {},
_ => { panic!("Failed to parse"); }
}
}
}
)*
}
};
}