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