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
extern crate nom;
use self::nom::Err;
use self::nom::IResult;
use self::nom::Needed;
pub trait TapNomOps<I, O, E> {
fn tap_done<R, F: FnOnce((&mut I, &mut O)) -> R>(self, f: F) -> Self;
fn tap_error<R, F: FnOnce(&mut Err<E>) -> R>(self, f: F) -> Self;
fn tap_incomplete<R, F: FnOnce(&mut Needed) -> R>(self, f: F) -> Self;
}
impl<I, O, E> TapNomOps<I, O, E> for IResult<I, O, E> {
fn tap_done<R, F: FnOnce((&mut I, &mut O)) -> R>(mut self, f: F) -> Self {
use self::nom::IResult::Done;
if let &mut Done(ref mut rem, ref mut val) = &mut self {
let _ = f((rem, val));
}
self
}
fn tap_error<R, F: FnOnce(&mut Err<E>) -> R>(mut self, f: F) -> Self {
use self::nom::IResult::Error;
if let &mut Error(ref mut err) = &mut self {
let _ = f(&mut *err);
}
self
}
fn tap_incomplete<R, F: FnOnce(&mut Needed) -> R>(mut self, f: F) -> Self {
use self::nom::IResult::Incomplete;
if let &mut Incomplete(ref mut needed) = &mut self {
let _ = f(needed);
}
self
}
}
#[cfg(test)]
mod tests {
use super::nom::ErrorKind;
use super::*;
type TestResult = IResult<&'static str, i32, u32>;
#[test]
fn done() {
let d: TestResult = IResult::Done(" 24", 42);
let mut n = 0;
d.tap_done(|(rem, val)| {
assert_eq!(val, &mut 42);
if let Ok(p) = rem.trim().parse::<i32>() {
n = p;
}
});
assert_eq!(n, 24);
}
#[test]
fn error() {
let e: TestResult = IResult::Error(ErrorKind::Custom('t' as u32));
let mut err_code = 0;
e.tap_error(|e| {
if let ErrorKind::Custom(c) = *e {
err_code = c;
}
});
assert_eq!(err_code, 116);
}
#[test]
#[should_panic]
fn incomplete() {
let i: TestResult = IResult::Incomplete(Needed::Unknown);
let mut more = 0;
i.tap_incomplete(|i| {
if let Needed::Size(s) = *i {
more = s;
} else {
panic!();
}
});
}
}