1 use crate::branch::{alt, permutation};
2 use crate::bytes::streaming::tag;
3 use crate::error::ErrorKind;
4 use crate::internal::{Err, IResult, Needed};
5 #[cfg(feature = "alloc")]
6 use crate::{
7 error::ParseError,
8 lib::std::{
9 fmt::Debug,
10 string::{String, ToString},
11 },
12 };
13
14 #[cfg(feature = "alloc")]
15 #[derive(Debug, Clone, PartialEq)]
16 pub struct ErrorStr(String);
17
18 #[cfg(feature = "alloc")]
19 impl From<u32> for ErrorStr {
from(i: u32) -> Self20 fn from(i: u32) -> Self {
21 ErrorStr(format!("custom error code: {}", i))
22 }
23 }
24
25 #[cfg(feature = "alloc")]
26 impl<'a> From<&'a str> for ErrorStr {
from(i: &'a str) -> Self27 fn from(i: &'a str) -> Self {
28 ErrorStr(format!("custom error message: {}", i))
29 }
30 }
31
32 #[cfg(feature = "alloc")]
33 impl<I: Debug> ParseError<I> for ErrorStr {
from_error_kind(input: I, kind: ErrorKind) -> Self34 fn from_error_kind(input: I, kind: ErrorKind) -> Self {
35 ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind))
36 }
37
append(input: I, kind: ErrorKind, other: Self) -> Self38 fn append(input: I, kind: ErrorKind, other: Self) -> Self {
39 ErrorStr(format!(
40 "custom error message: ({:?}, {:?}) - {:?}",
41 input, kind, other
42 ))
43 }
44 }
45
46 #[cfg(feature = "alloc")]
47 #[test]
alt_test()48 fn alt_test() {
49 fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
50 Ok((&b""[..], input))
51 }
52
53 #[allow(unused_variables)]
54 fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
55 Err(Err::Error(ErrorStr("abcd".to_string())))
56 }
57
58 fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
59 Ok((input, &b""[..]))
60 }
61
62 fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
63 alt((dont_work, dont_work))(i)
64 }
65 fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
66 alt((dont_work, work))(i)
67 }
68 fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> {
69 alt((dont_work, dont_work, work2, dont_work))(i)
70 }
71 //named!(alt1, alt!(dont_work | dont_work));
72 //named!(alt2, alt!(dont_work | work));
73 //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work));
74
75 let a = &b"abcd"[..];
76 assert_eq!(
77 alt1(a),
78 Err(Err::Error(error_node_position!(
79 a,
80 ErrorKind::Alt,
81 ErrorStr("abcd".to_string())
82 )))
83 );
84 assert_eq!(alt2(a), Ok((&b""[..], a)));
85 assert_eq!(alt3(a), Ok((a, &b""[..])));
86
87 fn alt4(i: &[u8]) -> IResult<&[u8], &[u8]> {
88 alt((tag("abcd"), tag("efgh")))(i)
89 }
90 let b = &b"efgh"[..];
91 assert_eq!(alt4(a), Ok((&b""[..], a)));
92 assert_eq!(alt4(b), Ok((&b""[..], b)));
93 }
94
95 #[test]
alt_incomplete()96 fn alt_incomplete() {
97 fn alt1(i: &[u8]) -> IResult<&[u8], &[u8]> {
98 alt((tag("a"), tag("bc"), tag("def")))(i)
99 }
100
101 let a = &b""[..];
102 assert_eq!(alt1(a), Err(Err::Incomplete(Needed::new(1))));
103 let a = &b"b"[..];
104 assert_eq!(alt1(a), Err(Err::Incomplete(Needed::new(1))));
105 let a = &b"bcd"[..];
106 assert_eq!(alt1(a), Ok((&b"d"[..], &b"bc"[..])));
107 let a = &b"cde"[..];
108 assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Tag))));
109 let a = &b"de"[..];
110 assert_eq!(alt1(a), Err(Err::Incomplete(Needed::new(1))));
111 let a = &b"defg"[..];
112 assert_eq!(alt1(a), Ok((&b"g"[..], &b"def"[..])));
113 }
114
115 #[test]
permutation_test()116 fn permutation_test() {
117 fn perm(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8], &[u8])> {
118 permutation((tag("abcd"), tag("efg"), tag("hi")))(i)
119 }
120
121 let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]);
122
123 let a = &b"abcdefghijk"[..];
124 assert_eq!(perm(a), Ok((&b"jk"[..], expected)));
125 let b = &b"efgabcdhijk"[..];
126 assert_eq!(perm(b), Ok((&b"jk"[..], expected)));
127 let c = &b"hiefgabcdjk"[..];
128 assert_eq!(perm(c), Ok((&b"jk"[..], expected)));
129
130 let d = &b"efgxyzabcdefghi"[..];
131 assert_eq!(
132 perm(d),
133 Err(Err::Error(error_node_position!(
134 &b"efgxyzabcdefghi"[..],
135 ErrorKind::Permutation,
136 error_position!(&b"xyzabcdefghi"[..], ErrorKind::Tag)
137 )))
138 );
139
140 let e = &b"efgabc"[..];
141 assert_eq!(perm(e), Err(Err::Incomplete(Needed::new(1))));
142 }
143