/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nom-8.0.0/src/bytes/mod.rs
Line | Count | Source |
1 | | //! Parsers recognizing bytes streams |
2 | | |
3 | | pub mod complete; |
4 | | pub mod streaming; |
5 | | #[cfg(test)] |
6 | | mod tests; |
7 | | |
8 | | use core::marker::PhantomData; |
9 | | |
10 | | use crate::error::ErrorKind; |
11 | | use crate::error::ParseError; |
12 | | use crate::internal::{Err, Needed, Parser}; |
13 | | use crate::lib::std::result::Result::*; |
14 | | use crate::traits::{Compare, CompareResult}; |
15 | | use crate::AsChar; |
16 | | use crate::Check; |
17 | | use crate::ExtendInto; |
18 | | use crate::FindSubstring; |
19 | | use crate::FindToken; |
20 | | use crate::Input; |
21 | | use crate::IsStreaming; |
22 | | use crate::Mode; |
23 | | use crate::OutputM; |
24 | | use crate::OutputMode; |
25 | | use crate::ToUsize; |
26 | | |
27 | | /// Recognizes a pattern. |
28 | | /// |
29 | | /// The input data will be compared to the tag combinator's argument and will return the part of |
30 | | /// the input that matches the argument. |
31 | | /// # Example |
32 | | /// ```rust |
33 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
34 | | /// use nom::bytes::streaming::tag; |
35 | | /// |
36 | | /// fn parser(s: &str) -> IResult<&str, &str> { |
37 | | /// tag("Hello")(s) |
38 | | /// } |
39 | | /// |
40 | | /// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello"))); |
41 | | /// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag)))); |
42 | | /// assert_eq!(parser("S"), Err(Err::Error(Error::new("S", ErrorKind::Tag)))); |
43 | | /// assert_eq!(parser("H"), Err(Err::Incomplete(Needed::new(4)))); |
44 | | /// ``` |
45 | 0 | pub fn tag<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
46 | 0 | where |
47 | 0 | I: Input + Compare<T>, |
48 | 0 | T: Input + Clone, |
49 | | { |
50 | 0 | Tag { |
51 | 0 | tag, |
52 | 0 | e: PhantomData, |
53 | 0 | } |
54 | 0 | } |
55 | | |
56 | | /// Tag implementation |
57 | | pub struct Tag<T, E> { |
58 | | tag: T, |
59 | | e: PhantomData<E>, |
60 | | } |
61 | | |
62 | | impl<I, Error: ParseError<I>, T> Parser<I> for Tag<T, Error> |
63 | | where |
64 | | I: Input + Compare<T>, |
65 | | T: Input + Clone, |
66 | | { |
67 | | type Output = I; |
68 | | |
69 | | type Error = Error; |
70 | | |
71 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
72 | 0 | let tag_len = self.tag.input_len(); |
73 | 0 | let t = self.tag.clone(); |
74 | | |
75 | 0 | match i.compare(t) { |
76 | 0 | CompareResult::Ok => Ok((i.take_from(tag_len), OM::Output::bind(|| i.take(tag_len)))), Unexecuted instantiation: <nom::bytes::Tag<&str, nom::error::Error<&str>> as nom::internal::Parser<&str>>::process::<nom::internal::OutputM<nom::internal::Emit, nom::internal::Emit, nom::internal::Complete>>::{closure#0}Unexecuted instantiation: <nom::bytes::Tag<_, _> as nom::internal::Parser<_>>::process::<_>::{closure#0} |
77 | | CompareResult::Incomplete => { |
78 | 0 | if OM::Incomplete::is_streaming() { |
79 | 0 | Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))) |
80 | | } else { |
81 | 0 | Err(Err::Error(OM::Error::bind(|| { |
82 | 0 | let e: ErrorKind = ErrorKind::Tag; |
83 | 0 | Error::from_error_kind(i, e) |
84 | 0 | }))) Unexecuted instantiation: <nom::bytes::Tag<&str, nom::error::Error<&str>> as nom::internal::Parser<&str>>::process::<nom::internal::OutputM<nom::internal::Emit, nom::internal::Emit, nom::internal::Complete>>::{closure#1}Unexecuted instantiation: <nom::bytes::Tag<_, _> as nom::internal::Parser<_>>::process::<_>::{closure#1} |
85 | | } |
86 | | } |
87 | 0 | CompareResult::Error => Err(Err::Error(OM::Error::bind(|| { |
88 | 0 | let e: ErrorKind = ErrorKind::Tag; |
89 | 0 | Error::from_error_kind(i, e) |
90 | 0 | }))), Unexecuted instantiation: <nom::bytes::Tag<&str, nom::error::Error<&str>> as nom::internal::Parser<&str>>::process::<nom::internal::OutputM<nom::internal::Emit, nom::internal::Emit, nom::internal::Complete>>::{closure#2}Unexecuted instantiation: <nom::bytes::Tag<_, _> as nom::internal::Parser<_>>::process::<_>::{closure#2} |
91 | | } |
92 | 0 | } Unexecuted instantiation: <nom::bytes::Tag<&str, nom::error::Error<&str>> as nom::internal::Parser<&str>>::process::<nom::internal::OutputM<nom::internal::Emit, nom::internal::Emit, nom::internal::Complete>> Unexecuted instantiation: <nom::bytes::Tag<_, _> as nom::internal::Parser<_>>::process::<_> |
93 | | } |
94 | | |
95 | | /// Recognizes a case insensitive pattern. |
96 | | /// |
97 | | /// The input data will be compared to the tag combinator's argument and will return the part of |
98 | | /// the input that matches the argument with no regard to case. |
99 | | /// # Example |
100 | | /// ```rust |
101 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
102 | | /// use nom::bytes::streaming::tag_no_case; |
103 | | /// |
104 | | /// fn parser(s: &str) -> IResult<&str, &str> { |
105 | | /// tag_no_case("hello")(s) |
106 | | /// } |
107 | | /// |
108 | | /// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello"))); |
109 | | /// assert_eq!(parser("hello, World!"), Ok((", World!", "hello"))); |
110 | | /// assert_eq!(parser("HeLlO, World!"), Ok((", World!", "HeLlO"))); |
111 | | /// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag)))); |
112 | | /// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(5)))); |
113 | | /// ``` |
114 | 0 | pub fn tag_no_case<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
115 | 0 | where |
116 | 0 | I: Input + Compare<T>, |
117 | 0 | T: Input + Clone, |
118 | | { |
119 | 0 | TagNoCase { |
120 | 0 | tag, |
121 | 0 | e: PhantomData, |
122 | 0 | } |
123 | 0 | } |
124 | | |
125 | | /// Case insensitive Tag implementation |
126 | | pub struct TagNoCase<T, E> { |
127 | | tag: T, |
128 | | e: PhantomData<E>, |
129 | | } |
130 | | |
131 | | impl<I, Error: ParseError<I>, T> Parser<I> for TagNoCase<T, Error> |
132 | | where |
133 | | I: Input + Compare<T>, |
134 | | T: Input + Clone, |
135 | | { |
136 | | type Output = I; |
137 | | |
138 | | type Error = Error; |
139 | | |
140 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
141 | 0 | let tag_len = self.tag.input_len(); |
142 | 0 | let t = self.tag.clone(); |
143 | | |
144 | 0 | match i.compare_no_case(t) { |
145 | 0 | CompareResult::Ok => Ok((i.take_from(tag_len), OM::Output::bind(|| i.take(tag_len)))), |
146 | | CompareResult::Incomplete => { |
147 | 0 | if OM::Incomplete::is_streaming() { |
148 | 0 | Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))) |
149 | | } else { |
150 | 0 | Err(Err::Error(OM::Error::bind(|| { |
151 | 0 | let e: ErrorKind = ErrorKind::Tag; |
152 | 0 | Error::from_error_kind(i, e) |
153 | 0 | }))) |
154 | | } |
155 | | } |
156 | 0 | CompareResult::Error => Err(Err::Error(OM::Error::bind(|| { |
157 | 0 | let e: ErrorKind = ErrorKind::Tag; |
158 | 0 | Error::from_error_kind(i, e) |
159 | 0 | }))), |
160 | | } |
161 | 0 | } |
162 | | } |
163 | | |
164 | | /// Parser wrapper for `split_at_position` |
165 | | pub struct SplitPosition<F, E> { |
166 | | predicate: F, |
167 | | error: PhantomData<E>, |
168 | | } |
169 | | |
170 | | impl<I, Error: ParseError<I>, F> Parser<I> for SplitPosition<F, Error> |
171 | | where |
172 | | I: Input, |
173 | | F: Fn(<I as Input>::Item) -> bool, |
174 | | { |
175 | | type Output = I; |
176 | | |
177 | | type Error = Error; |
178 | | |
179 | | #[inline(always)] |
180 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
181 | 0 | i.split_at_position_mode::<OM, _, _>(|c| (self.predicate)(c)) |
182 | 0 | } |
183 | | } |
184 | | |
185 | | /// Parser wrapper for `split_at_position1` |
186 | | pub struct SplitPosition1<F, E> { |
187 | | e: ErrorKind, |
188 | | predicate: F, |
189 | | error: PhantomData<E>, |
190 | | } |
191 | | |
192 | | impl<I, Error: ParseError<I>, F> Parser<I> for SplitPosition1<F, Error> |
193 | | where |
194 | | I: Input, |
195 | | F: Fn(<I as Input>::Item) -> bool, |
196 | | { |
197 | | type Output = I; |
198 | | |
199 | | type Error = Error; |
200 | | |
201 | | #[inline(always)] |
202 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
203 | 0 | i.split_at_position_mode1::<OM, _, _>(|c| (self.predicate)(c), self.e) |
204 | 0 | } |
205 | | } |
206 | | |
207 | | /// Parse till certain characters are met. |
208 | | /// |
209 | | /// The parser will return the longest slice till one of the characters of the combinator's argument are met. |
210 | | /// |
211 | | /// It doesn't consume the matched character. |
212 | | /// |
213 | | /// It will return a `Err::Error(("", ErrorKind::IsNot))` if the pattern wasn't met. |
214 | | /// # Example |
215 | | /// ```rust |
216 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
217 | | /// use nom::bytes::complete::is_not; |
218 | | /// |
219 | | /// fn not_space(s: &str) -> IResult<&str, &str> { |
220 | | /// is_not(" \t\r\n")(s) |
221 | | /// } |
222 | | /// |
223 | | /// assert_eq!(not_space("Hello, World!"), Ok((" World!", "Hello,"))); |
224 | | /// assert_eq!(not_space("Sometimes\t"), Ok(("\t", "Sometimes"))); |
225 | | /// assert_eq!(not_space("Nospace"), Ok(("", "Nospace"))); |
226 | | /// assert_eq!(not_space(""), Err(Err::Error(Error::new("", ErrorKind::IsNot)))); |
227 | | /// ``` |
228 | 0 | pub fn is_not<T, I, Error: ParseError<I>>(arr: T) -> impl Parser<I, Output = I, Error = Error> |
229 | 0 | where |
230 | 0 | I: Input, |
231 | 0 | T: FindToken<<I as Input>::Item>, |
232 | | { |
233 | | SplitPosition1 { |
234 | 0 | e: ErrorKind::IsNot, |
235 | 0 | predicate: move |c| arr.find_token(c), |
236 | 0 | error: PhantomData, |
237 | | } |
238 | 0 | } |
239 | | |
240 | | /// Returns the longest slice of the matches the pattern. |
241 | | /// |
242 | | /// The parser will return the longest slice consisting of the characters in provided in the |
243 | | /// combinator's argument. |
244 | | /// |
245 | | /// It will return a `Err(Err::Error((_, ErrorKind::IsA)))` if the pattern wasn't met. |
246 | | /// # Example |
247 | | /// ```rust |
248 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
249 | | /// use nom::bytes::complete::is_a; |
250 | | /// |
251 | | /// fn hex(s: &str) -> IResult<&str, &str> { |
252 | | /// is_a("1234567890ABCDEF")(s) |
253 | | /// } |
254 | | /// |
255 | | /// assert_eq!(hex("123 and voila"), Ok((" and voila", "123"))); |
256 | | /// assert_eq!(hex("DEADBEEF and others"), Ok((" and others", "DEADBEEF"))); |
257 | | /// assert_eq!(hex("BADBABEsomething"), Ok(("something", "BADBABE"))); |
258 | | /// assert_eq!(hex("D15EA5E"), Ok(("", "D15EA5E"))); |
259 | | /// assert_eq!(hex(""), Err(Err::Error(Error::new("", ErrorKind::IsA)))); |
260 | | /// ``` |
261 | 0 | pub fn is_a<T, I, Error: ParseError<I>>(arr: T) -> impl Parser<I, Output = I, Error = Error> |
262 | 0 | where |
263 | 0 | I: Input, |
264 | 0 | T: FindToken<<I as Input>::Item>, |
265 | | { |
266 | | SplitPosition1 { |
267 | 0 | e: ErrorKind::IsA, |
268 | 0 | predicate: move |c| !arr.find_token(c), |
269 | 0 | error: PhantomData, |
270 | | } |
271 | 0 | } |
272 | | |
273 | | /// Returns the longest input slice (if any) that matches the predicate. |
274 | | /// |
275 | | /// The parser will return the longest slice that matches the given predicate *(a function that |
276 | | /// takes the input and returns a bool)*. |
277 | | /// # Example |
278 | | /// ```rust |
279 | | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
280 | | /// use nom::bytes::complete::take_while; |
281 | | /// use nom::character::is_alphabetic; |
282 | | /// |
283 | | /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { |
284 | | /// take_while(is_alphabetic)(s) |
285 | | /// } |
286 | | /// |
287 | | /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); |
288 | | /// assert_eq!(alpha(b"12345"), Ok((&b"12345"[..], &b""[..]))); |
289 | | /// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..]))); |
290 | | /// assert_eq!(alpha(b""), Ok((&b""[..], &b""[..]))); |
291 | | /// ``` |
292 | 0 | pub fn take_while<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
293 | 0 | where |
294 | 0 | I: Input, |
295 | 0 | F: Fn(<I as Input>::Item) -> bool, |
296 | | { |
297 | | SplitPosition { |
298 | 0 | predicate: move |c| !cond(c), |
299 | 0 | error: PhantomData, |
300 | | } |
301 | 0 | } |
302 | | |
303 | | /// Returns the longest (at least 1) input slice that matches the predicate. |
304 | | /// |
305 | | /// The parser will return the longest slice that matches the given predicate *(a function that |
306 | | /// takes the input and returns a bool)*. |
307 | | /// |
308 | | /// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met. |
309 | | /// |
310 | | /// # Streaming Specific |
311 | | /// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` or if the pattern reaches the end of the input. |
312 | | /// |
313 | | /// # Example |
314 | | /// ```rust |
315 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
316 | | /// use nom::bytes::streaming::take_while1; |
317 | | /// use nom::character::is_alphabetic; |
318 | | /// |
319 | | /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { |
320 | | /// take_while1(is_alphabetic)(s) |
321 | | /// } |
322 | | /// |
323 | | /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); |
324 | | /// assert_eq!(alpha(b"latin"), Err(Err::Incomplete(Needed::new(1)))); |
325 | | /// assert_eq!(alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhile1)))); |
326 | | /// ``` |
327 | 0 | pub fn take_while1<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
328 | 0 | where |
329 | 0 | I: Input, |
330 | 0 | F: Fn(<I as Input>::Item) -> bool, |
331 | | { |
332 | | SplitPosition1 { |
333 | 0 | e: ErrorKind::TakeWhile1, |
334 | 0 | predicate: move |c| !cond(c), |
335 | 0 | error: PhantomData, |
336 | | } |
337 | 0 | } |
338 | | |
339 | | /// Returns the longest (m <= len <= n) input slice that matches the predicate. |
340 | | /// |
341 | | /// The parser will return the longest slice that matches the given predicate *(a function that |
342 | | /// takes the input and returns a bool)*. |
343 | | /// |
344 | | /// It will return an `Err::Error((_, ErrorKind::TakeWhileMN))` if the pattern wasn't met. |
345 | | /// # Streaming Specific |
346 | | /// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the pattern reaches the end of the input or is too short. |
347 | | /// |
348 | | /// # Example |
349 | | /// ```rust |
350 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
351 | | /// use nom::bytes::streaming::take_while_m_n; |
352 | | /// use nom::character::is_alphabetic; |
353 | | /// |
354 | | /// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { |
355 | | /// take_while_m_n(3, 6, is_alphabetic)(s) |
356 | | /// } |
357 | | /// |
358 | | /// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); |
359 | | /// assert_eq!(short_alpha(b"lengthy"), Ok((&b"y"[..], &b"length"[..]))); |
360 | | /// assert_eq!(short_alpha(b"latin"), Err(Err::Incomplete(Needed::new(1)))); |
361 | | /// assert_eq!(short_alpha(b"ed"), Err(Err::Incomplete(Needed::new(1)))); |
362 | | /// assert_eq!(short_alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhileMN)))); |
363 | | /// ``` |
364 | 0 | pub fn take_while_m_n<F, I, Error: ParseError<I>>( |
365 | 0 | m: usize, |
366 | 0 | n: usize, |
367 | 0 | predicate: F, |
368 | 0 | ) -> impl Parser<I, Output = I, Error = Error> |
369 | 0 | where |
370 | 0 | I: Input, |
371 | 0 | F: Fn(<I as Input>::Item) -> bool, |
372 | | { |
373 | 0 | TakeWhileMN { |
374 | 0 | m, |
375 | 0 | n, |
376 | 0 | predicate, |
377 | 0 | e: PhantomData, |
378 | 0 | } |
379 | 0 | } |
380 | | |
381 | | /// Parser implementation for [take_while_m_n] |
382 | | pub struct TakeWhileMN<F, E> { |
383 | | m: usize, |
384 | | n: usize, |
385 | | predicate: F, |
386 | | e: PhantomData<E>, |
387 | | } |
388 | | |
389 | | impl<I, Error: ParseError<I>, F> Parser<I> for TakeWhileMN<F, Error> |
390 | | where |
391 | | I: Input, |
392 | | F: Fn(<I as Input>::Item) -> bool, |
393 | | { |
394 | | type Output = I; |
395 | | type Error = Error; |
396 | | |
397 | 0 | fn process<OM: OutputMode>( |
398 | 0 | &mut self, |
399 | 0 | input: I, |
400 | 0 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
401 | 0 | let mut count = 0; |
402 | 0 | for (i, (index, item)) in input.iter_indices().enumerate() { |
403 | 0 | if i == self.n { |
404 | | return Ok(( |
405 | 0 | input.take_from(index), |
406 | 0 | OM::Output::bind(|| input.take(index)), |
407 | | )); |
408 | 0 | } |
409 | | |
410 | 0 | if !(self.predicate)(item) { |
411 | 0 | if i >= self.m { |
412 | | return Ok(( |
413 | 0 | input.take_from(index), |
414 | 0 | OM::Output::bind(|| input.take(index)), |
415 | | )); |
416 | | } else { |
417 | 0 | return Err(Err::Error(OM::Error::bind(|| { |
418 | 0 | Error::from_error_kind(input, ErrorKind::TakeWhileMN) |
419 | 0 | }))); |
420 | | } |
421 | 0 | } |
422 | 0 | count += 1; |
423 | | } |
424 | | |
425 | 0 | let input_len = input.input_len(); |
426 | 0 | if OM::Incomplete::is_streaming() { |
427 | 0 | let needed = if self.m > input_len { |
428 | 0 | self.m - input_len |
429 | | } else { |
430 | 0 | 1 |
431 | | }; |
432 | 0 | Err(Err::Incomplete(Needed::new(needed))) |
433 | 0 | } else if count >= self.m { |
434 | | Ok(( |
435 | 0 | input.take_from(input_len), |
436 | 0 | OM::Output::bind(|| input.take(input_len)), |
437 | | )) |
438 | | } else { |
439 | 0 | Err(Err::Error(OM::Error::bind(|| { |
440 | 0 | Error::from_error_kind(input, ErrorKind::TakeWhileMN) |
441 | 0 | }))) |
442 | | } |
443 | 0 | } |
444 | | } |
445 | | |
446 | | /// Returns the longest input slice (if any) till a predicate is met. |
447 | | /// |
448 | | /// The parser will return the longest slice till the given predicate *(a function that |
449 | | /// takes the input and returns a bool)*. |
450 | | /// # Example |
451 | | /// ```rust |
452 | | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
453 | | /// use nom::bytes::complete::take_till; |
454 | | /// |
455 | | /// fn till_colon(s: &str) -> IResult<&str, &str> { |
456 | | /// take_till(|c| c == ':')(s) |
457 | | /// } |
458 | | /// |
459 | | /// assert_eq!(till_colon("latin:123"), Ok((":123", "latin"))); |
460 | | /// assert_eq!(till_colon(":empty matched"), Ok((":empty matched", ""))); //allowed |
461 | | /// assert_eq!(till_colon("12345"), Ok(("", "12345"))); |
462 | | /// assert_eq!(till_colon(""), Ok(("", ""))); |
463 | | /// ``` |
464 | | #[allow(clippy::redundant_closure)] |
465 | 0 | pub fn take_till<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
466 | 0 | where |
467 | 0 | I: Input, |
468 | 0 | F: Fn(<I as Input>::Item) -> bool, |
469 | | { |
470 | 0 | SplitPosition { |
471 | 0 | predicate: cond, |
472 | 0 | error: PhantomData, |
473 | 0 | } |
474 | 0 | } |
475 | | |
476 | | /// Returns the longest (at least 1) input slice till a predicate is met. |
477 | | /// |
478 | | /// The parser will return the longest slice till the given predicate *(a function that |
479 | | /// takes the input and returns a bool)*. |
480 | | /// |
481 | | /// # Streaming Specific |
482 | | /// *Streaming version* will return a `Err::Incomplete(Needed::new(1))` if the match reaches the |
483 | | /// end of input or if there was not match. |
484 | | /// # Example |
485 | | /// ```rust |
486 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
487 | | /// use nom::bytes::streaming::take_till1; |
488 | | /// |
489 | | /// fn till_colon(s: &str) -> IResult<&str, &str> { |
490 | | /// take_till1(|c| c == ':')(s) |
491 | | /// } |
492 | | /// |
493 | | /// assert_eq!(till_colon("latin:123"), Ok((":123", "latin"))); |
494 | | /// assert_eq!(till_colon(":empty matched"), Err(Err::Error(Error::new(":empty matched", ErrorKind::TakeTill1)))); |
495 | | /// assert_eq!(till_colon("12345"), Err(Err::Incomplete(Needed::new(1)))); |
496 | | /// assert_eq!(till_colon(""), Err(Err::Incomplete(Needed::new(1)))); |
497 | | /// ``` |
498 | | #[allow(clippy::redundant_closure)] |
499 | 0 | pub fn take_till1<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error> |
500 | 0 | where |
501 | 0 | I: Input, |
502 | 0 | F: Fn(<I as Input>::Item) -> bool, |
503 | | { |
504 | 0 | SplitPosition1 { |
505 | 0 | e: ErrorKind::TakeTill1, |
506 | 0 | predicate: cond, |
507 | 0 | error: PhantomData, |
508 | 0 | } |
509 | 0 | } |
510 | | |
511 | | /// Returns an input slice containing the first N input elements (Input[..N]). |
512 | | /// |
513 | | /// # Streaming Specific |
514 | | /// *Streaming version* if the input has less than N elements, `take` will |
515 | | /// return a `Err::Incomplete(Needed::new(M))` where M is the number of |
516 | | /// additional bytes the parser would need to succeed. |
517 | | /// It is well defined for `&[u8]` as the number of elements is the byte size, |
518 | | /// but for types like `&str`, we cannot know how many bytes correspond for |
519 | | /// the next few chars, so the result will be `Err::Incomplete(Needed::Unknown)` |
520 | | /// |
521 | | /// # Example |
522 | | /// ```rust |
523 | | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
524 | | /// use nom::bytes::streaming::take; |
525 | | /// |
526 | | /// fn take6(s: &str) -> IResult<&str, &str> { |
527 | | /// take(6usize)(s) |
528 | | /// } |
529 | | /// |
530 | | /// assert_eq!(take6("1234567"), Ok(("7", "123456"))); |
531 | | /// assert_eq!(take6("things"), Ok(("", "things"))); |
532 | | /// assert_eq!(take6("short"), Err(Err::Incomplete(Needed::Unknown))); |
533 | | /// ``` |
534 | 0 | pub fn take<C, I, Error: ParseError<I>>(count: C) -> impl Parser<I, Output = I, Error = Error> |
535 | 0 | where |
536 | 0 | I: Input, |
537 | 0 | C: ToUsize, |
538 | | { |
539 | 0 | Take { |
540 | 0 | length: count.to_usize(), |
541 | 0 | e: PhantomData, |
542 | 0 | } |
543 | 0 | } |
544 | | |
545 | | /// Parser implementation for [take] |
546 | | pub struct Take<E> { |
547 | | length: usize, |
548 | | e: PhantomData<E>, |
549 | | } |
550 | | |
551 | | impl<I, Error: ParseError<I>> Parser<I> for Take<Error> |
552 | | where |
553 | | I: Input, |
554 | | { |
555 | | type Output = I; |
556 | | type Error = Error; |
557 | | |
558 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
559 | 0 | match i.slice_index(self.length) { |
560 | 0 | Err(needed) => { |
561 | 0 | if OM::Incomplete::is_streaming() { |
562 | 0 | Err(Err::Incomplete(needed)) |
563 | | } else { |
564 | 0 | Err(Err::Error(OM::Error::bind(|| { |
565 | 0 | let e: ErrorKind = ErrorKind::Eof; |
566 | 0 | Error::from_error_kind(i, e) |
567 | 0 | }))) |
568 | | } |
569 | | } |
570 | 0 | Ok(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))), |
571 | | } |
572 | 0 | } |
573 | | } |
574 | | |
575 | | /// Returns the input slice up to the first occurrence of the pattern. |
576 | | /// |
577 | | /// It doesn't consume the pattern. |
578 | | /// |
579 | | /// # Streaming Specific |
580 | | /// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't |
581 | | /// contain the pattern or if the input is smaller than the pattern. |
582 | | /// # Example |
583 | | /// ```rust |
584 | | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
585 | | /// use nom::bytes::streaming::take_until; |
586 | | /// |
587 | | /// fn until_eof(s: &str) -> IResult<&str, &str> { |
588 | | /// take_until("eof")(s) |
589 | | /// } |
590 | | /// |
591 | | /// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world"))); |
592 | | /// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown))); |
593 | | /// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown))); |
594 | | /// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1"))); |
595 | | /// ``` |
596 | 0 | pub fn take_until<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
597 | 0 | where |
598 | 0 | I: Input + FindSubstring<T>, |
599 | 0 | T: Clone, |
600 | | { |
601 | 0 | TakeUntil { |
602 | 0 | tag, |
603 | 0 | e: PhantomData, |
604 | 0 | } |
605 | 0 | } |
606 | | |
607 | | /// Parser implementation for [take_until] |
608 | | pub struct TakeUntil<T, E> { |
609 | | tag: T, |
610 | | e: PhantomData<E>, |
611 | | } |
612 | | |
613 | | impl<I, T, Error: ParseError<I>> Parser<I> for TakeUntil<T, Error> |
614 | | where |
615 | | I: Input + FindSubstring<T>, |
616 | | T: Clone, |
617 | | { |
618 | | type Output = I; |
619 | | type Error = Error; |
620 | | |
621 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
622 | 0 | match i.find_substring(self.tag.clone()) { |
623 | | None => { |
624 | 0 | if OM::Incomplete::is_streaming() { |
625 | 0 | Err(Err::Incomplete(Needed::Unknown)) |
626 | | } else { |
627 | 0 | Err(Err::Error(OM::Error::bind(|| { |
628 | 0 | let e: ErrorKind = ErrorKind::TakeUntil; |
629 | 0 | Error::from_error_kind(i, e) |
630 | 0 | }))) |
631 | | } |
632 | | } |
633 | 0 | Some(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))), |
634 | | } |
635 | 0 | } |
636 | | } |
637 | | |
638 | | /// Returns the non empty input slice up to the first occurrence of the pattern. |
639 | | /// |
640 | | /// It doesn't consume the pattern. |
641 | | /// |
642 | | /// # Streaming Specific |
643 | | /// *Streaming version* will return a `Err::Incomplete(Needed::new(N))` if the input doesn't |
644 | | /// contain the pattern or if the input is smaller than the pattern. |
645 | | /// # Example |
646 | | /// ```rust |
647 | | /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; |
648 | | /// use nom::bytes::streaming::take_until1; |
649 | | /// |
650 | | /// fn until_eof(s: &str) -> IResult<&str, &str> { |
651 | | /// take_until1("eof")(s) |
652 | | /// } |
653 | | /// |
654 | | /// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world"))); |
655 | | /// assert_eq!(until_eof("hello, world"), Err(Err::Incomplete(Needed::Unknown))); |
656 | | /// assert_eq!(until_eof("hello, worldeo"), Err(Err::Incomplete(Needed::Unknown))); |
657 | | /// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1"))); |
658 | | /// assert_eq!(until_eof("eof"), Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil)))); |
659 | | /// ``` |
660 | 0 | pub fn take_until1<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error> |
661 | 0 | where |
662 | 0 | I: Input + FindSubstring<T>, |
663 | 0 | T: Clone, |
664 | | { |
665 | 0 | TakeUntil1 { |
666 | 0 | tag, |
667 | 0 | e: PhantomData, |
668 | 0 | } |
669 | 0 | } |
670 | | |
671 | | /// Parser implementation for take_until1 |
672 | | pub struct TakeUntil1<T, E> { |
673 | | tag: T, |
674 | | e: PhantomData<E>, |
675 | | } |
676 | | |
677 | | impl<I, T, Error: ParseError<I>> Parser<I> for TakeUntil1<T, Error> |
678 | | where |
679 | | I: Input + FindSubstring<T>, |
680 | | T: Clone, |
681 | | { |
682 | | type Output = I; |
683 | | type Error = Error; |
684 | | |
685 | 0 | fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
686 | 0 | match i.find_substring(self.tag.clone()) { |
687 | | None => { |
688 | 0 | if OM::Incomplete::is_streaming() { |
689 | 0 | Err(Err::Incomplete(Needed::Unknown)) |
690 | | } else { |
691 | 0 | Err(Err::Error(OM::Error::bind(|| { |
692 | 0 | let e: ErrorKind = ErrorKind::TakeUntil; |
693 | 0 | Error::from_error_kind(i, e) |
694 | 0 | }))) |
695 | | } |
696 | | } |
697 | 0 | Some(0) => Err(Err::Error(OM::Error::bind(|| { |
698 | 0 | Error::from_error_kind(i, ErrorKind::TakeUntil) |
699 | 0 | }))), |
700 | | |
701 | 0 | Some(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))), |
702 | | } |
703 | 0 | } |
704 | | } |
705 | | |
706 | | /// Matches a byte string with escaped characters. |
707 | | /// |
708 | | /// * The first argument matches the normal characters (it must not accept the control character) |
709 | | /// * The second argument is the control character (like `\` in most languages) |
710 | | /// * The third argument matches the escaped characters |
711 | | /// # Example |
712 | | /// ``` |
713 | | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
714 | | /// # use nom::character::complete::digit1; |
715 | | /// use nom::bytes::streaming::escaped; |
716 | | /// use nom::character::streaming::one_of; |
717 | | /// |
718 | | /// fn esc(s: &str) -> IResult<&str, &str> { |
719 | | /// escaped(digit1, '\\', one_of("\"n\\"))(s) |
720 | | /// } |
721 | | /// |
722 | | /// assert_eq!(esc("123;"), Ok((";", "123"))); |
723 | | /// assert_eq!(esc("12\\\"34;"), Ok((";", "12\\\"34"))); |
724 | | /// ``` |
725 | | /// |
726 | 0 | pub fn escaped<I, Error, F, G>( |
727 | 0 | normal: F, |
728 | 0 | control_char: char, |
729 | 0 | escapable: G, |
730 | 0 | ) -> impl Parser<I, Output = I, Error = Error> |
731 | 0 | where |
732 | 0 | I: Input + Clone + crate::traits::Offset, |
733 | 0 | <I as Input>::Item: crate::traits::AsChar, |
734 | 0 | F: Parser<I, Error = Error>, |
735 | 0 | G: Parser<I, Error = Error>, |
736 | 0 | Error: ParseError<I>, |
737 | | { |
738 | 0 | Escaped { |
739 | 0 | normal, |
740 | 0 | escapable, |
741 | 0 | control_char, |
742 | 0 | e: PhantomData, |
743 | 0 | } |
744 | 0 | } |
745 | | |
746 | | /// Parser implementation for [escaped] |
747 | | pub struct Escaped<F, G, E> { |
748 | | normal: F, |
749 | | escapable: G, |
750 | | control_char: char, |
751 | | e: PhantomData<E>, |
752 | | } |
753 | | |
754 | | impl<I, Error: ParseError<I>, F, G> Parser<I> for Escaped<F, G, Error> |
755 | | where |
756 | | I: Input + Clone + crate::traits::Offset, |
757 | | <I as Input>::Item: crate::traits::AsChar, |
758 | | F: Parser<I, Error = Error>, |
759 | | G: Parser<I, Error = Error>, |
760 | | Error: ParseError<I>, |
761 | | { |
762 | | type Output = I; |
763 | | type Error = Error; |
764 | | |
765 | 0 | fn process<OM: OutputMode>( |
766 | 0 | &mut self, |
767 | 0 | input: I, |
768 | 0 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
769 | 0 | let mut i = input.clone(); |
770 | | |
771 | 0 | while i.input_len() > 0 { |
772 | 0 | let current_len = i.input_len(); |
773 | | |
774 | 0 | match self |
775 | 0 | .normal |
776 | 0 | .process::<OutputM<Check, Check, OM::Incomplete>>(i.clone()) |
777 | | { |
778 | 0 | Ok((i2, _)) => { |
779 | 0 | if i2.input_len() == 0 { |
780 | 0 | if OM::Incomplete::is_streaming() { |
781 | 0 | return Err(Err::Incomplete(Needed::Unknown)); |
782 | | } else { |
783 | 0 | let index = input.input_len(); |
784 | | return Ok(( |
785 | 0 | input.take_from(index), |
786 | 0 | OM::Output::bind(|| input.take(index)), |
787 | | )); |
788 | | } |
789 | 0 | } else if i2.input_len() == current_len { |
790 | 0 | let index = input.offset(&i2); |
791 | | return Ok(( |
792 | 0 | input.take_from(index), |
793 | 0 | OM::Output::bind(|| input.take(index)), |
794 | | )); |
795 | 0 | } else { |
796 | 0 | i = i2; |
797 | 0 | } |
798 | | } |
799 | | Err(Err::Error(_)) => { |
800 | | // unwrap() should be safe here since index < $i.input_len() |
801 | 0 | if i.iter_elements().next().unwrap().as_char() == self.control_char { |
802 | 0 | let next = self.control_char.len_utf8(); |
803 | 0 | if next >= i.input_len() { |
804 | 0 | if OM::Incomplete::is_streaming() { |
805 | 0 | return Err(Err::Incomplete(Needed::new(1))); |
806 | | } else { |
807 | 0 | return Err(Err::Error(OM::Error::bind(|| { |
808 | 0 | Error::from_error_kind(input, ErrorKind::Escaped) |
809 | 0 | }))); |
810 | | } |
811 | | } else { |
812 | 0 | match self |
813 | 0 | .escapable |
814 | 0 | .process::<OutputM<Check, OM::Error, OM::Incomplete>>(i.take_from(next)) |
815 | | { |
816 | 0 | Ok((i2, _)) => { |
817 | 0 | if i2.input_len() == 0 { |
818 | 0 | if OM::Incomplete::is_streaming() { |
819 | 0 | return Err(Err::Incomplete(Needed::Unknown)); |
820 | | } else { |
821 | 0 | let index = input.input_len(); |
822 | | return Ok(( |
823 | 0 | input.take_from(index), |
824 | 0 | OM::Output::bind(|| input.take(index)), |
825 | | )); |
826 | | } |
827 | 0 | } else { |
828 | 0 | i = i2; |
829 | 0 | } |
830 | | } |
831 | 0 | Err(e) => return Err(e), |
832 | | } |
833 | | } |
834 | | } else { |
835 | 0 | let index = input.offset(&i); |
836 | 0 | if index == 0 { |
837 | 0 | return Err(Err::Error(OM::Error::bind(|| { |
838 | 0 | Error::from_error_kind(input, ErrorKind::Escaped) |
839 | 0 | }))); |
840 | | } else { |
841 | | return Ok(( |
842 | 0 | input.take_from(index), |
843 | 0 | OM::Output::bind(|| input.take(index)), |
844 | | )); |
845 | | } |
846 | | } |
847 | | } |
848 | 0 | Err(Err::Failure(e)) => { |
849 | 0 | return Err(Err::Failure(e)); |
850 | | } |
851 | 0 | Err(Err::Incomplete(i)) => { |
852 | 0 | return Err(Err::Incomplete(i)); |
853 | | } |
854 | | } |
855 | | } |
856 | | |
857 | 0 | if OM::Incomplete::is_streaming() { |
858 | 0 | Err(Err::Incomplete(Needed::Unknown)) |
859 | | } else { |
860 | 0 | let index = input.input_len(); |
861 | | Ok(( |
862 | 0 | input.take_from(index), |
863 | 0 | OM::Output::bind(|| input.take(index)), |
864 | | )) |
865 | | } |
866 | 0 | } |
867 | | } |
868 | | |
869 | | /// Matches a byte string with escaped characters. |
870 | | /// |
871 | | /// * The first argument matches the normal characters (it must not match the control character) |
872 | | /// * The second argument is the control character (like `\` in most languages) |
873 | | /// * The third argument matches the escaped characters and transforms them |
874 | | /// |
875 | | /// As an example, the chain `abc\tdef` could be `abc def` (it also consumes the control character) |
876 | | /// |
877 | | /// ``` |
878 | | /// # use nom::{Err, error::ErrorKind, Needed, IResult}; |
879 | | /// # use std::str::from_utf8; |
880 | | /// use nom::bytes::streaming::{escaped_transform, tag}; |
881 | | /// use nom::character::streaming::alpha1; |
882 | | /// use nom::branch::alt; |
883 | | /// use nom::combinator::value; |
884 | | /// |
885 | | /// fn parser(input: &str) -> IResult<&str, String> { |
886 | | /// escaped_transform( |
887 | | /// alpha1, |
888 | | /// '\\', |
889 | | /// alt(( |
890 | | /// value("\\", tag("\\")), |
891 | | /// value("\"", tag("\"")), |
892 | | /// value("\n", tag("n")), |
893 | | /// )) |
894 | | /// )(input) |
895 | | /// } |
896 | | /// |
897 | | /// assert_eq!(parser("ab\\\"cd\""), Ok(("\"", String::from("ab\"cd")))); |
898 | | /// ``` |
899 | | #[cfg(feature = "alloc")] |
900 | | #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] |
901 | 0 | pub fn escaped_transform<I, Error, F, G, ExtendItem, Output>( |
902 | 0 | normal: F, |
903 | 0 | control_char: char, |
904 | 0 | transform: G, |
905 | 0 | ) -> impl Parser<I, Output = Output, Error = Error> |
906 | 0 | where |
907 | 0 | I: Clone + crate::traits::Offset + Input, |
908 | 0 | I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
909 | 0 | <F as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
910 | 0 | <G as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
911 | 0 | <I as Input>::Item: crate::traits::AsChar, |
912 | 0 | F: Parser<I, Error = Error>, |
913 | 0 | G: Parser<I, Error = Error>, |
914 | 0 | Error: ParseError<I>, |
915 | | { |
916 | 0 | EscapedTransform { |
917 | 0 | normal, |
918 | 0 | control_char, |
919 | 0 | transform, |
920 | 0 | e: PhantomData, |
921 | 0 | extend: PhantomData, |
922 | 0 | o: PhantomData, |
923 | 0 | } |
924 | 0 | } |
925 | | |
926 | | /// Parser implementation for [escaped_transform] |
927 | | pub struct EscapedTransform<F, G, E, ExtendItem, Output> { |
928 | | normal: F, |
929 | | transform: G, |
930 | | control_char: char, |
931 | | e: PhantomData<E>, |
932 | | extend: PhantomData<ExtendItem>, |
933 | | o: PhantomData<Output>, |
934 | | } |
935 | | |
936 | | impl<I, Error: ParseError<I>, F, G, ExtendItem, Output> Parser<I> |
937 | | for EscapedTransform<F, G, Error, ExtendItem, Output> |
938 | | where |
939 | | I: Clone + crate::traits::Offset + Input, |
940 | | I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
941 | | <F as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
942 | | <G as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, |
943 | | <I as Input>::Item: crate::traits::AsChar, |
944 | | F: Parser<I, Error = Error>, |
945 | | G: Parser<I, Error = Error>, |
946 | | Error: ParseError<I>, |
947 | | { |
948 | | type Output = Output; |
949 | | type Error = Error; |
950 | | |
951 | 0 | fn process<OM: OutputMode>( |
952 | 0 | &mut self, |
953 | 0 | input: I, |
954 | 0 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
955 | 0 | let mut index = 0; |
956 | 0 | let mut res = OM::Output::bind(|| input.new_builder()); |
957 | | |
958 | 0 | while index < input.input_len() { |
959 | 0 | let current_len = input.input_len(); |
960 | 0 | let remainder = input.take_from(index); |
961 | 0 | match self.normal.process::<OM>(remainder.clone()) { |
962 | 0 | Ok((i2, o)) => { |
963 | 0 | res = OM::Output::combine(o, res, |o, mut res| { |
964 | 0 | o.extend_into(&mut res); |
965 | 0 | res |
966 | 0 | }); |
967 | 0 | if i2.input_len() == 0 { |
968 | 0 | if OM::Incomplete::is_streaming() { |
969 | 0 | return Err(Err::Incomplete(Needed::Unknown)); |
970 | | } else { |
971 | 0 | let index = input.input_len(); |
972 | 0 | return Ok((input.take_from(index), res)); |
973 | | } |
974 | 0 | } else if i2.input_len() == current_len { |
975 | 0 | return Ok((remainder, res)); |
976 | 0 | } else { |
977 | 0 | index = input.offset(&i2); |
978 | 0 | } |
979 | | } |
980 | | Err(Err::Error(_)) => { |
981 | | // unwrap() should be safe here since index < $i.input_len() |
982 | 0 | if remainder.iter_elements().next().unwrap().as_char() == self.control_char { |
983 | 0 | let next = index + self.control_char.len_utf8(); |
984 | 0 | let input_len = input.input_len(); |
985 | | |
986 | 0 | if next >= input_len { |
987 | 0 | if OM::Incomplete::is_streaming() { |
988 | 0 | return Err(Err::Incomplete(Needed::Unknown)); |
989 | | } else { |
990 | 0 | return Err(Err::Error(OM::Error::bind(|| { |
991 | 0 | Error::from_error_kind(remainder, ErrorKind::EscapedTransform) |
992 | 0 | }))); |
993 | | } |
994 | | } else { |
995 | 0 | match self.transform.process::<OM>(input.take_from(next)) { |
996 | 0 | Ok((i2, o)) => { |
997 | 0 | res = OM::Output::combine(o, res, |o, mut res| { |
998 | 0 | o.extend_into(&mut res); |
999 | 0 | res |
1000 | 0 | }); |
1001 | 0 | if i2.input_len() == 0 { |
1002 | 0 | if OM::Incomplete::is_streaming() { |
1003 | 0 | return Err(Err::Incomplete(Needed::Unknown)); |
1004 | | } else { |
1005 | 0 | return Ok((input.take_from(input.input_len()), res)); |
1006 | | } |
1007 | 0 | } else { |
1008 | 0 | index = input.offset(&i2); |
1009 | 0 | } |
1010 | | } |
1011 | 0 | Err(Err::Error(e)) => return Err(Err::Error(e)), |
1012 | 0 | Err(Err::Failure(e)) => { |
1013 | 0 | return Err(Err::Failure(e)); |
1014 | | } |
1015 | 0 | Err(Err::Incomplete(i)) => { |
1016 | 0 | return Err(Err::Incomplete(i)); |
1017 | | } |
1018 | | } |
1019 | | } |
1020 | | } else { |
1021 | 0 | if index == 0 { |
1022 | 0 | return Err(Err::Error(OM::Error::bind(|| { |
1023 | 0 | Error::from_error_kind(remainder, ErrorKind::EscapedTransform) |
1024 | 0 | }))); |
1025 | 0 | } |
1026 | 0 | return Ok((remainder, res)); |
1027 | | } |
1028 | | } |
1029 | 0 | Err(Err::Failure(e)) => { |
1030 | 0 | return Err(Err::Failure(e)); |
1031 | | } |
1032 | 0 | Err(Err::Incomplete(i)) => { |
1033 | 0 | return Err(Err::Incomplete(i)); |
1034 | | } |
1035 | | } |
1036 | | } |
1037 | | |
1038 | 0 | if OM::Incomplete::is_streaming() { |
1039 | 0 | Err(Err::Incomplete(Needed::Unknown)) |
1040 | | } else { |
1041 | 0 | Ok((input.take_from(index), res)) |
1042 | | } |
1043 | 0 | } |
1044 | | } |