1 #[cfg(feature = "verbose-errors")]
2 #[cfg(feature = "std")]
3 use internal::{Err, IResult};
4 #[cfg(feature = "verbose-errors")]
5 use verbose_errors::Context;
6 
7 #[cfg(feature = "std")]
8 use std::collections::HashMap;
9 
10 #[cfg(feature = "alloc")]
11 use lib::std::string::ToString;
12 #[cfg(feature = "alloc")]
13 use lib::std::vec::Vec;
14 
15 #[cfg(feature = "std")]
16 pub trait HexDisplay {
17   /// Converts the value of `self` to a hex dump, returning the owned
18   /// string.
to_hex(&self, chunk_size: usize) -> String19   fn to_hex(&self, chunk_size: usize) -> String;
20 
21   /// Converts the value of `self` to a hex dump beginning at `from` address, returning the owned
22   /// string.
to_hex_from(&self, chunk_size: usize, from: usize) -> String23   fn to_hex_from(&self, chunk_size: usize, from: usize) -> String;
24 }
25 
26 #[cfg(feature = "std")]
27 static CHARS: &'static [u8] = b"0123456789abcdef";
28 
29 #[cfg(feature = "std")]
30 impl HexDisplay for [u8] {
31   #[allow(unused_variables)]
to_hex(&self, chunk_size: usize) -> String32   fn to_hex(&self, chunk_size: usize) -> String {
33     self.to_hex_from(chunk_size, 0)
34   }
35 
36   #[allow(unused_variables)]
to_hex_from(&self, chunk_size: usize, from: usize) -> String37   fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
38     let mut v = Vec::with_capacity(self.len() * 3);
39     let mut i = from;
40     for chunk in self.chunks(chunk_size) {
41       let s = format!("{:08x}", i);
42       for &ch in s.as_bytes().iter() {
43         v.push(ch);
44       }
45       v.push(b'\t');
46 
47       i += chunk_size;
48 
49       for &byte in chunk {
50         v.push(CHARS[(byte >> 4) as usize]);
51         v.push(CHARS[(byte & 0xf) as usize]);
52         v.push(b' ');
53       }
54       if chunk_size > chunk.len() {
55         for j in 0..(chunk_size - chunk.len()) {
56           v.push(b' ');
57           v.push(b' ');
58           v.push(b' ');
59         }
60       }
61       v.push(b'\t');
62 
63       for &byte in chunk {
64         if (byte >= 32 && byte <= 126) || byte >= 128 {
65           v.push(byte);
66         } else {
67           v.push(b'.');
68         }
69       }
70       v.push(b'\n');
71     }
72 
73     String::from_utf8_lossy(&v[..]).into_owned()
74   }
75 }
76 
77 #[cfg(feature = "std")]
78 impl HexDisplay for str {
79   #[allow(unused_variables)]
to_hex(&self, chunk_size: usize) -> String80   fn to_hex(&self, chunk_size: usize) -> String {
81     self.to_hex_from(chunk_size, 0)
82   }
83 
84   #[allow(unused_variables)]
to_hex_from(&self, chunk_size: usize, from: usize) -> String85   fn to_hex_from(&self, chunk_size: usize, from: usize) -> String {
86     self.as_bytes().to_hex_from(chunk_size, from)
87   }
88 }
89 
90 /// Prints a message if the parser fails
91 ///
92 /// The message prints the `Error` or `Incomplete`
93 /// and the parser's calling code
94 ///
95 /// ```
96 /// # #[macro_use] extern crate nom;
97 /// # fn main() {
98 ///    named!(f, dbg!( tag!( "abcd" ) ) );
99 ///
100 ///    let a = &b"efgh"[..];
101 ///
102 ///    // Will print the following message:
103 ///    // Error(Position(0, [101, 102, 103, 104])) at l.5 by ' tag ! ( "abcd" ) '
104 ///    f(a);
105 /// # }
106 /// ```
107 #[macro_export]
108 macro_rules! dbg (
109   ($i: expr, $submac:ident!( $($args:tt)* )) => (
110     {
111       use $crate::lib::std::result::Result::*;
112       let l = line!();
113       match $submac!($i, $($args)*) {
114         Err(e) => {
115           println!("Err({:?}) at l.{} by ' {} '", e, l, stringify!($submac!($($args)*)));
116           Err(e)
117         },
118         a => a,
119       }
120     }
121   );
122 
123   ($i:expr, $f:ident) => (
124       dbg!($i, call!($f));
125   );
126 );
127 
128 /// Prints a message and the input if the parser fails
129 ///
130 /// The message prints the `Error` or `Incomplete`
131 /// and the parser's calling code.
132 ///
133 /// It also displays the input in hexdump format
134 ///
135 /// ```ignore
136 /// # #[macro_use] extern crate nom;
137 /// # fn main() {
138 ///    named!(f, dbg_dmp!( tag!( "abcd" ) ) );
139 ///
140 ///    let a = &b"efghijkl"[..];
141 ///
142 ///    // Will print the following message:
143 ///    // Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by ' tag ! ( "abcd" ) '
144 ///    // 00000000        65 66 67 68 69 6a 6b 6c         efghijkl
145 ///    f(a);
146 /// # }
147 #[macro_export]
148 macro_rules! dbg_dmp (
149   ($i: expr, $submac:ident!( $($args:tt)* )) => (
150     {
151       use $crate::HexDisplay;
152       let l = line!();
153       match $submac!($i, $($args)*) {
154         Err(e) => {
155           println!("Error({:?}) at l.{} by ' {} '\n{}", e, l, stringify!($submac!($($args)*)), $i.to_hex(8));
156           Err(e)
157         },
158         a => a,
159       }
160     }
161   );
162 
163   ($i:expr, $f:ident) => (
164       dbg_dmp!($i, call!($f));
165   );
166 );
167 
168 #[cfg(feature = "verbose-errors")]
error_to_list<P: Clone, E: Clone>(e: &Context<P, E>) -> Vec<(P, ErrorKind<E>)>169 pub fn error_to_list<P: Clone, E: Clone>(e: &Context<P, E>) -> Vec<(P, ErrorKind<E>)> {
170   match e {
171     &Context::Code(ref i, ref err) => {
172       let mut v = Vec::new();
173       v.push((i.clone(), err.clone()));
174       return v;
175     }
176     &Context::List(ref v) => {
177       let mut v2 = v.clone();
178       v2.reverse();
179       v2
180     }
181   }
182 }
183 
184 #[cfg(feature = "verbose-errors")]
compare_error_paths<P: Clone + PartialEq, E: Clone + PartialEq>(e1: &Context<P, E>, e2: &Context<P, E>) -> bool185 pub fn compare_error_paths<P: Clone + PartialEq, E: Clone + PartialEq>(e1: &Context<P, E>, e2: &Context<P, E>) -> bool {
186   error_to_list(e1) == error_to_list(e2)
187 }
188 
189 #[cfg(feature = "std")]
190 #[cfg(feature = "verbose-errors")]
191 use lib::std::hash::Hash;
192 
193 #[cfg(feature = "std")]
194 #[cfg(feature = "verbose-errors")]
add_error_pattern<'a, I: Clone + Hash + Eq, O, E: Clone + Hash + Eq>( h: &mut HashMap<Vec<(I, ErrorKind<E>)>, &'a str>, res: IResult<I, O, E>, message: &'a str, ) -> bool195 pub fn add_error_pattern<'a, I: Clone + Hash + Eq, O, E: Clone + Hash + Eq>(
196   h: &mut HashMap<Vec<(I, ErrorKind<E>)>, &'a str>,
197   res: IResult<I, O, E>,
198   message: &'a str,
199 ) -> bool {
200   match res {
201     Err(Err::Error(e)) | Err(Err::Failure(e)) => {
202       h.insert(error_to_list(&e), message);
203       true
204     }
205     _ => false,
206   }
207 }
208 
slice_to_offsets(input: &[u8], s: &[u8]) -> (usize, usize)209 pub fn slice_to_offsets(input: &[u8], s: &[u8]) -> (usize, usize) {
210   let start = input.as_ptr();
211   let off1 = s.as_ptr() as usize - start as usize;
212   let off2 = off1 + s.len();
213   (off1, off2)
214 }
215 
216 #[cfg(feature = "std")]
217 #[cfg(feature = "verbose-errors")]
prepare_errors<O, E: Clone>(input: &[u8], res: IResult<&[u8], O, E>) -> Option<Vec<(ErrorKind<E>, usize, usize)>>218 pub fn prepare_errors<O, E: Clone>(input: &[u8], res: IResult<&[u8], O, E>) -> Option<Vec<(ErrorKind<E>, usize, usize)>> {
219   if let Err(Err::Error(e)) = res {
220     let mut v: Vec<(ErrorKind<E>, usize, usize)> = Vec::new();
221 
222     match e {
223       Context::Code(p, kind) => {
224         let (o1, o2) = slice_to_offsets(input, p);
225         v.push((kind, o1, o2));
226       }
227       Context::List(mut l) => {
228         for (p, kind) in l.drain(..) {
229           let (o1, o2) = slice_to_offsets(input, p);
230           v.push((kind, o1, o2));
231         }
232 
233         v.reverse()
234       }
235     }
236 
237     v.sort_by(|a, b| a.1.cmp(&b.1));
238     Some(v)
239   } else {
240     None
241   }
242 }
243 
244 #[cfg(feature = "std")]
245 #[cfg(feature = "verbose-errors")]
print_error<O, E: Clone>(input: &[u8], res: IResult<&[u8], O, E>)246 pub fn print_error<O, E: Clone>(input: &[u8], res: IResult<&[u8], O, E>) {
247   if let Some(v) = prepare_errors(input, res) {
248     let colors = generate_colors(&v);
249     println!("parser codes: {}", print_codes(&colors, &HashMap::new()));
250     println!("{}", print_offsets(input, 0, &v));
251   } else {
252     println!("not an error");
253   }
254 }
255 
256 #[cfg(feature = "std")]
257 #[cfg(feature = "verbose-errors")]
generate_colors<E>(v: &[(ErrorKind<E>, usize, usize)]) -> HashMap<u32, u8>258 pub fn generate_colors<E>(v: &[(ErrorKind<E>, usize, usize)]) -> HashMap<u32, u8> {
259   let mut h: HashMap<u32, u8> = HashMap::new();
260   let mut color = 0;
261 
262   for &(ref c, _, _) in v.iter() {
263     h.insert(error_to_u32(c), color + 31);
264     color = color + 1 % 7;
265   }
266 
267   h
268 }
269 
code_from_offset<E>(v: &[(ErrorKind<E>, usize, usize)], offset: usize) -> Option<u32>270 pub fn code_from_offset<E>(v: &[(ErrorKind<E>, usize, usize)], offset: usize) -> Option<u32> {
271   let mut acc: Option<(u32, usize, usize)> = None;
272   for &(ref ek, s, e) in v.iter() {
273     let c = error_to_u32(ek);
274     if s <= offset && offset <= e {
275       if let Some((_, start, end)) = acc {
276         if start <= s && e <= end {
277           acc = Some((c, s, e));
278         }
279       } else {
280         acc = Some((c, s, e));
281       }
282     }
283   }
284   if let Some((code, _, _)) = acc {
285     return Some(code);
286   } else {
287     return None;
288   }
289 }
290 
291 #[cfg(feature = "alloc")]
reset_color(v: &mut Vec<u8>)292 pub fn reset_color(v: &mut Vec<u8>) {
293   v.push(0x1B);
294   v.push(b'[');
295   v.push(0);
296   v.push(b'm');
297 }
298 
299 #[cfg(feature = "alloc")]
write_color(v: &mut Vec<u8>, color: u8)300 pub fn write_color(v: &mut Vec<u8>, color: u8) {
301   v.push(0x1B);
302   v.push(b'[');
303   v.push(1);
304   v.push(b';');
305   let s = color.to_string();
306   let bytes = s.as_bytes();
307   v.extend(bytes.iter().cloned());
308   v.push(b'm');
309 }
310 
311 #[cfg(feature = "std")]
312 #[cfg_attr(feature = "cargo-clippy", allow(implicit_hasher))]
print_codes(colors: &HashMap<u32, u8>, names: &HashMap<u32, &str>) -> String313 pub fn print_codes(colors: &HashMap<u32, u8>, names: &HashMap<u32, &str>) -> String {
314   let mut v = Vec::new();
315   for (code, &color) in colors {
316     if let Some(&s) = names.get(code) {
317       let bytes = s.as_bytes();
318       write_color(&mut v, color);
319       v.extend(bytes.iter().cloned());
320     } else {
321       let s = code.to_string();
322       let bytes = s.as_bytes();
323       write_color(&mut v, color);
324       v.extend(bytes.iter().cloned());
325     }
326     reset_color(&mut v);
327     v.push(b' ');
328   }
329   reset_color(&mut v);
330 
331   String::from_utf8_lossy(&v[..]).into_owned()
332 }
333 
334 #[cfg(feature = "std")]
335 #[cfg(feature = "verbose-errors")]
print_offsets<E>(input: &[u8], from: usize, offsets: &[(ErrorKind<E>, usize, usize)]) -> String336 pub fn print_offsets<E>(input: &[u8], from: usize, offsets: &[(ErrorKind<E>, usize, usize)]) -> String {
337   let mut v = Vec::with_capacity(input.len() * 3);
338   let mut i = from;
339   let chunk_size = 8;
340   let mut current_code: Option<u32> = None;
341   let mut current_code2: Option<u32> = None;
342 
343   let colors = generate_colors(&offsets);
344 
345   for chunk in input.chunks(chunk_size) {
346     let s = format!("{:08x}", i);
347     for &ch in s.as_bytes().iter() {
348       v.push(ch);
349     }
350     v.push(b'\t');
351 
352     let mut k = i;
353     let mut l = i;
354     for &byte in chunk {
355       if let Some(code) = code_from_offset(&offsets, k) {
356         if let Some(current) = current_code {
357           if current != code {
358             reset_color(&mut v);
359             current_code = Some(code);
360             if let Some(&color) = colors.get(&code) {
361               write_color(&mut v, color);
362             }
363           }
364         } else {
365           current_code = Some(code);
366           if let Some(&color) = colors.get(&code) {
367             write_color(&mut v, color);
368           }
369         }
370       }
371       v.push(CHARS[(byte >> 4) as usize]);
372       v.push(CHARS[(byte & 0xf) as usize]);
373       v.push(b' ');
374       k = k + 1;
375     }
376 
377     reset_color(&mut v);
378 
379     if chunk_size > chunk.len() {
380       for _ in 0..(chunk_size - chunk.len()) {
381         v.push(b' ');
382         v.push(b' ');
383         v.push(b' ');
384       }
385     }
386     v.push(b'\t');
387 
388     for &byte in chunk {
389       if let Some(code) = code_from_offset(&offsets, l) {
390         if let Some(current) = current_code2 {
391           if current != code {
392             reset_color(&mut v);
393             current_code2 = Some(code);
394             if let Some(&color) = colors.get(&code) {
395               write_color(&mut v, color);
396             }
397           }
398         } else {
399           current_code2 = Some(code);
400           if let Some(&color) = colors.get(&code) {
401             write_color(&mut v, color);
402           }
403         }
404       }
405       if (byte >= 32 && byte <= 126) || byte >= 128 {
406         v.push(byte);
407       } else {
408         v.push(b'.');
409       }
410       l = l + 1;
411     }
412     reset_color(&mut v);
413 
414     v.push(b'\n');
415     i = i + chunk_size;
416   }
417 
418   String::from_utf8_lossy(&v[..]).into_owned()
419 }
420 
421 /// indicates which parser returned an error
422 #[cfg_attr(rustfmt, rustfmt_skip)]
423 #[derive(Debug,PartialEq,Eq,Hash,Clone)]
424 #[allow(deprecated)]
425 pub enum ErrorKind<E = u32> {
426   Custom(E),
427   Tag,
428   MapRes,
429   MapOpt,
430   Alt,
431   IsNot,
432   IsA,
433   SeparatedList,
434   SeparatedNonEmptyList,
435   Many0,
436   Many1,
437   ManyTill,
438   Count,
439   TakeUntilAndConsume,
440   TakeUntil,
441   TakeUntilEitherAndConsume,
442   TakeUntilEither,
443   LengthValue,
444   TagClosure,
445   Alpha,
446   Digit,
447   HexDigit,
448   OctDigit,
449   AlphaNumeric,
450   Space,
451   MultiSpace,
452   LengthValueFn,
453   Eof,
454   ExprOpt,
455   ExprRes,
456   CondReduce,
457   Switch,
458   TagBits,
459   OneOf,
460   NoneOf,
461   Char,
462   CrLf,
463   RegexpMatch,
464   RegexpMatches,
465   RegexpFind,
466   RegexpCapture,
467   RegexpCaptures,
468   TakeWhile1,
469   Complete,
470   Fix,
471   Escaped,
472   EscapedTransform,
473   #[deprecated(since = "4.0.0", note = "Please use `Tag` instead")]
474   TagStr,
475   #[deprecated(since = "4.0.0", note = "Please use `IsNot` instead")]
476   IsNotStr,
477   #[deprecated(since = "4.0.0", note = "Please use `IsA` instead")]
478   IsAStr,
479   #[deprecated(since = "4.0.0", note = "Please use `TakeWhile1` instead")]
480   TakeWhile1Str,
481   NonEmpty,
482   ManyMN,
483   #[deprecated(since = "4.0.0", note = "Please use `TakeUntilAndConsume` instead")]
484   TakeUntilAndConsumeStr,
485   #[deprecated(since = "4.0.0", note = "Please use `TakeUntil` instead")]
486   TakeUntilStr,
487   Not,
488   Permutation,
489   Verify,
490   TakeTill1,
491   TakeUntilAndConsume1,
492   TakeWhileMN,
493   ParseTo,
494 }
495 
496 #[cfg_attr(rustfmt, rustfmt_skip)]
497 #[allow(deprecated)]
error_to_u32<E>(e: &ErrorKind<E>) -> u32498 pub fn error_to_u32<E>(e: &ErrorKind<E>) -> u32 {
499   match *e {
500     ErrorKind::Custom(_)                 => 0,
501     ErrorKind::Tag                       => 1,
502     ErrorKind::MapRes                    => 2,
503     ErrorKind::MapOpt                    => 3,
504     ErrorKind::Alt                       => 4,
505     ErrorKind::IsNot                     => 5,
506     ErrorKind::IsA                       => 6,
507     ErrorKind::SeparatedList             => 7,
508     ErrorKind::SeparatedNonEmptyList     => 8,
509     ErrorKind::Many1                     => 9,
510     ErrorKind::Count                     => 10,
511     ErrorKind::TakeUntilAndConsume       => 11,
512     ErrorKind::TakeUntil                 => 12,
513     ErrorKind::TakeUntilEitherAndConsume => 13,
514     ErrorKind::TakeUntilEither           => 14,
515     ErrorKind::LengthValue               => 15,
516     ErrorKind::TagClosure                => 16,
517     ErrorKind::Alpha                     => 17,
518     ErrorKind::Digit                     => 18,
519     ErrorKind::AlphaNumeric              => 19,
520     ErrorKind::Space                     => 20,
521     ErrorKind::MultiSpace                => 21,
522     ErrorKind::LengthValueFn             => 22,
523     ErrorKind::Eof                       => 23,
524     ErrorKind::ExprOpt                   => 24,
525     ErrorKind::ExprRes                   => 25,
526     ErrorKind::CondReduce                => 26,
527     ErrorKind::Switch                    => 27,
528     ErrorKind::TagBits                   => 28,
529     ErrorKind::OneOf                     => 29,
530     ErrorKind::NoneOf                    => 30,
531     ErrorKind::Char                      => 40,
532     ErrorKind::CrLf                      => 41,
533     ErrorKind::RegexpMatch               => 42,
534     ErrorKind::RegexpMatches             => 43,
535     ErrorKind::RegexpFind                => 44,
536     ErrorKind::RegexpCapture             => 45,
537     ErrorKind::RegexpCaptures            => 46,
538     ErrorKind::TakeWhile1                => 47,
539     ErrorKind::Complete                  => 48,
540     ErrorKind::Fix                       => 49,
541     ErrorKind::Escaped                   => 50,
542     ErrorKind::EscapedTransform          => 51,
543     ErrorKind::TagStr                    => 52,
544     ErrorKind::IsNotStr                  => 53,
545     ErrorKind::IsAStr                    => 54,
546     ErrorKind::TakeWhile1Str             => 55,
547     ErrorKind::NonEmpty                  => 56,
548     ErrorKind::ManyMN                    => 57,
549     ErrorKind::TakeUntilAndConsumeStr    => 58,
550     ErrorKind::HexDigit                  => 59,
551     ErrorKind::TakeUntilStr              => 60,
552     ErrorKind::OctDigit                  => 61,
553     ErrorKind::Many0                     => 62,
554     ErrorKind::Not                       => 63,
555     ErrorKind::Permutation               => 64,
556     ErrorKind::ManyTill                  => 65,
557     ErrorKind::Verify                    => 66,
558     ErrorKind::TakeTill1                 => 67,
559     ErrorKind::TakeUntilAndConsume1      => 68,
560     ErrorKind::TakeWhileMN               => 69,
561     ErrorKind::ParseTo                   => 70,
562   }
563 }
564 
565 impl<E> ErrorKind<E> {
566   #[cfg_attr(rustfmt, rustfmt_skip)]
567   #[allow(deprecated)]
description(&self) -> &str568   pub fn description(&self) -> &str {
569     match *self {
570       ErrorKind::Custom(_)                 => "Custom error",
571       ErrorKind::Tag                       => "Tag",
572       ErrorKind::MapRes                    => "Map on Result",
573       ErrorKind::MapOpt                    => "Map on Option",
574       ErrorKind::Alt                       => "Alternative",
575       ErrorKind::IsNot                     => "IsNot",
576       ErrorKind::IsA                       => "IsA",
577       ErrorKind::SeparatedList             => "Separated list",
578       ErrorKind::SeparatedNonEmptyList     => "Separated non empty list",
579       ErrorKind::Many0                     => "Many0",
580       ErrorKind::Many1                     => "Many1",
581       ErrorKind::Count                     => "Count",
582       ErrorKind::TakeUntilAndConsume       => "Take until and consume",
583       ErrorKind::TakeUntil                 => "Take until",
584       ErrorKind::TakeUntilEitherAndConsume => "Take until either and consume",
585       ErrorKind::TakeUntilEither           => "Take until either",
586       ErrorKind::LengthValue               => "Length followed by value",
587       ErrorKind::TagClosure                => "Tag closure",
588       ErrorKind::Alpha                     => "Alphabetic",
589       ErrorKind::Digit                     => "Digit",
590       ErrorKind::AlphaNumeric              => "AlphaNumeric",
591       ErrorKind::Space                     => "Space",
592       ErrorKind::MultiSpace                => "Multiple spaces",
593       ErrorKind::LengthValueFn             => "LengthValueFn",
594       ErrorKind::Eof                       => "End of file",
595       ErrorKind::ExprOpt                   => "Evaluate Option",
596       ErrorKind::ExprRes                   => "Evaluate Result",
597       ErrorKind::CondReduce                => "Condition reduce",
598       ErrorKind::Switch                    => "Switch",
599       ErrorKind::TagBits                   => "Tag on bitstream",
600       ErrorKind::OneOf                     => "OneOf",
601       ErrorKind::NoneOf                    => "NoneOf",
602       ErrorKind::Char                      => "Char",
603       ErrorKind::CrLf                      => "CrLf",
604       ErrorKind::RegexpMatch               => "RegexpMatch",
605       ErrorKind::RegexpMatches             => "RegexpMatches",
606       ErrorKind::RegexpFind                => "RegexpFind",
607       ErrorKind::RegexpCapture             => "RegexpCapture",
608       ErrorKind::RegexpCaptures            => "RegexpCaptures",
609       ErrorKind::TakeWhile1                => "TakeWhile1",
610       ErrorKind::Complete                  => "Complete",
611       ErrorKind::Fix                       => "Fix",
612       ErrorKind::Escaped                   => "Escaped",
613       ErrorKind::EscapedTransform          => "EscapedTransform",
614       ErrorKind::TagStr                    => "Tag on strings",
615       ErrorKind::IsNotStr                  => "IsNot on strings",
616       ErrorKind::IsAStr                    => "IsA on strings",
617       ErrorKind::TakeWhile1Str             => "TakeWhile1 on strings",
618       ErrorKind::NonEmpty                  => "NonEmpty",
619       ErrorKind::ManyMN                    => "Many(m, n)",
620       ErrorKind::TakeUntilAndConsumeStr    => "Take until and consume on strings",
621       ErrorKind::HexDigit                  => "Hexadecimal Digit",
622       ErrorKind::TakeUntilStr              => "Take until on strings",
623       ErrorKind::OctDigit                  => "Octal digit",
624       ErrorKind::Not                       => "Negation",
625       ErrorKind::Permutation               => "Permutation",
626       ErrorKind::ManyTill                  => "ManyTill",
627       ErrorKind::Verify                    => "predicate verification",
628       ErrorKind::TakeTill1                 => "TakeTill1",
629       ErrorKind::TakeUntilAndConsume1      => "Take at least 1 until and consume",
630       ErrorKind::TakeWhileMN               => "TakeWhileMN",
631       ErrorKind::ParseTo                   => "Parse string to the specified type",
632     }
633   }
634 
635   /// Convert Err into an ErrorKind.
636   ///
637   /// This allows application code to use ErrorKind and stay independent from the `verbose-errors` features activation.
into_error_kind(self) -> ErrorKind<E>638   pub fn into_error_kind(self) -> ErrorKind<E> {
639     self
640   }
641 }
642 
643 pub trait Convert<T> {
convert(T) -> Self644   fn convert(T) -> Self;
645 }
646 
647 impl<F, E: From<F>> Convert<ErrorKind<F>> for ErrorKind<E> {
648   #[cfg_attr(rustfmt, rustfmt_skip)]
649   #[allow(deprecated)]
convert(e: ErrorKind<F>) -> Self650   fn convert(e: ErrorKind<F>) -> Self {
651     match e {
652       ErrorKind::Custom(c)                 => ErrorKind::Custom(E::from(c)),
653       ErrorKind::Tag                       => ErrorKind::Tag,
654       ErrorKind::MapRes                    => ErrorKind::MapRes,
655       ErrorKind::MapOpt                    => ErrorKind::MapOpt,
656       ErrorKind::Alt                       => ErrorKind::Alt,
657       ErrorKind::IsNot                     => ErrorKind::IsNot,
658       ErrorKind::IsA                       => ErrorKind::IsA,
659       ErrorKind::SeparatedList             => ErrorKind::SeparatedList,
660       ErrorKind::SeparatedNonEmptyList     => ErrorKind::SeparatedNonEmptyList,
661       ErrorKind::Many1                     => ErrorKind::Many1,
662       ErrorKind::Count                     => ErrorKind::Count,
663       ErrorKind::TakeUntilAndConsume       => ErrorKind::TakeUntilAndConsume,
664       ErrorKind::TakeUntil                 => ErrorKind::TakeUntil,
665       ErrorKind::TakeUntilEitherAndConsume => ErrorKind::TakeUntilEitherAndConsume,
666       ErrorKind::TakeUntilEither           => ErrorKind::TakeUntilEither,
667       ErrorKind::LengthValue               => ErrorKind::LengthValue,
668       ErrorKind::TagClosure                => ErrorKind::TagClosure,
669       ErrorKind::Alpha                     => ErrorKind::Alpha,
670       ErrorKind::Digit                     => ErrorKind::Digit,
671       ErrorKind::AlphaNumeric              => ErrorKind::AlphaNumeric,
672       ErrorKind::Space                     => ErrorKind::Space,
673       ErrorKind::MultiSpace                => ErrorKind::MultiSpace,
674       ErrorKind::LengthValueFn             => ErrorKind::LengthValueFn,
675       ErrorKind::Eof                       => ErrorKind::Eof,
676       ErrorKind::ExprOpt                   => ErrorKind::ExprOpt,
677       ErrorKind::ExprRes                   => ErrorKind::ExprRes,
678       ErrorKind::CondReduce                => ErrorKind::CondReduce,
679       ErrorKind::Switch                    => ErrorKind::Switch,
680       ErrorKind::TagBits                   => ErrorKind::TagBits,
681       ErrorKind::OneOf                     => ErrorKind::OneOf,
682       ErrorKind::NoneOf                    => ErrorKind::NoneOf,
683       ErrorKind::Char                      => ErrorKind::Char,
684       ErrorKind::CrLf                      => ErrorKind::CrLf,
685       ErrorKind::RegexpMatch               => ErrorKind::RegexpMatch,
686       ErrorKind::RegexpMatches             => ErrorKind::RegexpMatches,
687       ErrorKind::RegexpFind                => ErrorKind::RegexpFind,
688       ErrorKind::RegexpCapture             => ErrorKind::RegexpCapture,
689       ErrorKind::RegexpCaptures            => ErrorKind::RegexpCaptures,
690       ErrorKind::TakeWhile1                => ErrorKind::TakeWhile1,
691       ErrorKind::Complete                  => ErrorKind::Complete,
692       ErrorKind::Fix                       => ErrorKind::Fix,
693       ErrorKind::Escaped                   => ErrorKind::Escaped,
694       ErrorKind::EscapedTransform          => ErrorKind::EscapedTransform,
695       ErrorKind::TagStr                    => ErrorKind::TagStr,
696       ErrorKind::IsNotStr                  => ErrorKind::IsNotStr,
697       ErrorKind::IsAStr                    => ErrorKind::IsAStr,
698       ErrorKind::TakeWhile1Str             => ErrorKind::TakeWhile1Str,
699       ErrorKind::NonEmpty                  => ErrorKind::NonEmpty,
700       ErrorKind::ManyMN                    => ErrorKind::ManyMN,
701       ErrorKind::TakeUntilAndConsumeStr    => ErrorKind::TakeUntilAndConsumeStr,
702       ErrorKind::HexDigit                  => ErrorKind::HexDigit,
703       ErrorKind::TakeUntilStr              => ErrorKind::TakeUntilStr,
704       ErrorKind::OctDigit                  => ErrorKind::OctDigit,
705       ErrorKind::Many0                     => ErrorKind::Many0,
706       ErrorKind::Not                       => ErrorKind::Not,
707       ErrorKind::Permutation               => ErrorKind::Permutation,
708       ErrorKind::ManyTill                  => ErrorKind::ManyTill,
709       ErrorKind::Verify                    => ErrorKind::Verify,
710       ErrorKind::TakeTill1                 => ErrorKind::TakeTill1,
711       ErrorKind::TakeUntilAndConsume1      => ErrorKind::TakeUntilAndConsume1,
712       ErrorKind::TakeWhileMN               => ErrorKind::TakeWhileMN,
713       ErrorKind::ParseTo                   => ErrorKind::ParseTo,
714     }
715   }
716 }
717