1use std::error::Error as StdError;
2use std::fmt::{self, Debug};
3use std::str::FromStr;
4
5#[derive(Debug, PartialEq)]
7pub enum ParseErrorKind {
8 StartedIndented,
9 MixedIndent,
10 TabsWithSpaces,
11 SpacesWithTabs,
12 FileReadError,
13}
14
15#[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
53pub enum ValueParseError<T: FromStr> {
58 NoValue,
60 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}