confindent/
error.rs

1use std::error::Error as StdError;
2use std::fmt::{self, Debug};
3use std::str::FromStr;
4
5/// What kind of error happened? Oh, ParseErrorKind of error.
6#[derive(Debug, PartialEq)]
7pub enum ParseErrorKind {
8	StartedIndented,
9	MixedIndent,
10	TabsWithSpaces,
11	SpacesWithTabs,
12	FileReadError,
13}
14
15/// Our main error type.
16#[derive(Debug, PartialEq)]
17pub struct ParseError {
18	pub line: usize,
19	pub kind: ParseErrorKind,
20}
21
22impl StdError for ParseError {}
23impl fmt::Display for ParseError {
24	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25		match self.kind {
26			ParseErrorKind::StartedIndented => {
27				write!(
28					f,
29					"Cannot start document with an indented section. Line {}",
30					self.line
31				)
32			}
33			ParseErrorKind::MixedIndent => {
34				write!(
35					f,
36					"Indent mixed between tabs and spaces on line {}",
37					self.line
38				)
39			}
40			ParseErrorKind::TabsWithSpaces => {
41				write!(f, "Tabular indent in space block. Line {}", self.line)
42			}
43			ParseErrorKind::SpacesWithTabs => {
44				write!(f, "Space indent in tab block. Line {}", self.line)
45			}
46			ParseErrorKind::FileReadError => {
47				write!(f, "Failed to open file!")
48			}
49		}
50	}
51}
52
53/// Error returned when parsing a value fails
54///
55/// ValueParseError will implement `Display`, `Debug`, `PartialEq`, and `Error`
56/// as long `<T as FromStr>::Err` implements them.
57pub enum ValueParseError<T: FromStr> {
58	/// There was no value present to even try and parse
59	NoValue,
60	/// A value was present but the parse failed. The error is in this enum tuple.
61	ParseError(<T as FromStr>::Err),
62}
63
64impl<T: FromStr> StdError for ValueParseError<T> where <T as FromStr>::Err: StdError {}
65
66impl<T: FromStr> fmt::Display for ValueParseError<T>
67where
68	<T as FromStr>::Err: fmt::Display,
69{
70	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71		match self {
72			ValueParseError::NoValue => write!(f, "There was no value to parse present"),
73			ValueParseError::ParseError(e) => {
74				write!(f, "Failed to parse configuration value: {}", e)
75			}
76		}
77	}
78}
79
80impl<T: FromStr> fmt::Debug for ValueParseError<T>
81where
82	<T as FromStr>::Err: fmt::Debug,
83{
84	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85		match self {
86			ValueParseError::NoValue => f.debug_tuple("NoValue").finish(),
87			ValueParseError::ParseError(e) => f.debug_tuple("ParseError").field(e).finish(),
88		}
89	}
90}
91
92impl<T: FromStr> PartialEq for ValueParseError<T>
93where
94	<T as FromStr>::Err: PartialEq,
95{
96	fn eq(&self, other: &Self) -> bool {
97		if self == &Self::NoValue && other == &Self::NoValue {
98			true
99		} else if let Self::ParseError(e0) = self {
100			if let Self::ParseError(e1) = other {
101				e0 == e1
102			} else {
103				false
104			}
105		} else {
106			false
107		}
108	}
109}