freedesktop_entry_parser/
errors.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use nom::error::{Error as NomError, ErrorKind};
6use std::error::Error;
7use std::fmt::{Debug, Display};
8use std::str::Utf8Error;
9
10/// An error that occurred while parsing. This is the general error type for
11/// this library.
12#[derive(Debug)]
13pub enum ParseError {
14    /// Parser encountered some other error.
15    /// This is probably the most common error.
16    Other {
17        /// Remain input when error occurred.
18        at: ErrorBytes,
19        /// Type of nom parser error.
20        kind: ErrorKind,
21    },
22    /// Parser couldn't finish due to incomplete input.
23    Incomplete,
24    /// A UTF-8 encoding error.
25    Utf8Error { bytes: Vec<u8>, source: Utf8Error },
26}
27
28impl Display for ParseError {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        match self {
31            ParseError::Other { at, kind } => {
32                write!(f, "Error parings input: {} at {at}", kind.description())
33            }
34            ParseError::Incomplete => write!(f, "Incomplete input"),
35            ParseError::Utf8Error { source, .. } => Display::fmt(&source, f),
36        }
37    }
38}
39impl Error for ParseError {}
40
41/// The remaining input from the parser.  Useful for debugging to see where the
42/// parser failed.  This is used in [`ParseError`](struct.ParseError.html).
43/// It'll be `Valid` if the remaining input was a valid string and `Invalid` if
44/// it wasn't
45#[derive(Debug)]
46pub enum ErrorBytes {
47    /// Input was a valid string
48    Valid(String),
49    /// Input was not a valid string
50    Invalid(Vec<u8>),
51}
52
53impl Display for ErrorBytes {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        match self {
56            ErrorBytes::Valid(str) => Display::fmt(&str, f),
57            ErrorBytes::Invalid(bytes) => Debug::fmt(&bytes, f),
58        }
59    }
60}
61
62impl Error for ErrorBytes {}
63
64impl From<nom::Err<NomError<&[u8]>>> for ParseError {
65    fn from(e: nom::Err<NomError<&[u8]>>) -> Self {
66        match e {
67            nom::Err::Error(NomError { input, code })
68            | nom::Err::Failure(NomError { input, code }) => {
69                match std::str::from_utf8(input) {
70                    Ok(s) => ParseError::Other {
71                        at: ErrorBytes::Valid(s.to_owned()),
72                        kind: code,
73                    },
74                    Err(_) => ParseError::Other {
75                        at: ErrorBytes::Invalid(input.to_vec()),
76                        kind: code,
77                    },
78                }
79            }
80            nom::Err::Incomplete(_) => ParseError::Incomplete,
81        }
82    }
83}