pom_trace/
result.rs

1use std::error;
2use std::fmt::{self, Display};
3
4#[derive(Debug, PartialEq, Eq, Clone, Copy)]
5pub enum RollbackType {
6	Fail = 0,
7	Stop,
8}
9
10// Change to tree to allow for readable forks
11#[derive(Debug, PartialEq, Clone)]
12pub struct RollbackRecord {
13	pub name: String,
14	pub position: usize,
15	pub typ: RollbackType,
16	pub inner: Option<Box<Error>>,
17	pub previous_tracks: Vec<RollbackRecord>,
18}
19
20impl RollbackRecord {
21	fn fmt_with_indent(&self, f: &mut fmt::Formatter, indent: usize) -> fmt::Result {
22		let idnt = "  ".repeat(indent);
23		match &self.previous_tracks[..] {
24			[] => {}
25			[prev] => prev.fmt_with_indent(f, indent)?,
26			_ => {
27				writeln!(f, "{}Fork: {{", idnt)?;
28				for prev in &self.previous_tracks {
29					writeln!(f, "{}>><<", idnt)?;
30					prev.fmt_with_indent(f, indent + 1)?;
31				}
32				writeln!(f, "{}}}", idnt)?;
33			}
34		}
35		let rollback_type = match self.typ {
36			RollbackType::Fail => "failed",
37			RollbackType::Stop => "stopped",
38		};
39		match &self.inner {
40			Some(ref inner) => writeln!(
41				f,
42				"{}{} {} at {}, (inner: {})",
43				idnt, &self.name, rollback_type, &self.position, inner
44			)?,
45			None => writeln!(
46				f,
47				"{}{} {} at {}",
48				idnt, &self.name, rollback_type, &self.position
49			)?,
50		}
51		Ok(())
52	}
53}
54
55impl Display for RollbackRecord {
56	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57		self.fmt_with_indent(f, 0)
58	}
59}
60
61/// Parser error.
62#[derive(Debug, PartialEq, Clone)]
63pub enum Error {
64	Incomplete,
65	Mismatch {
66		message: String,
67		position: usize,
68		continuation_error: Option<Box<Error>>,
69	},
70	Conversion {
71		message: String,
72		position: usize,
73	},
74	Expect {
75		message: String,
76		position: usize,
77		inner: Box<Error>,
78	},
79	Custom {
80		message: String,
81		position: usize,
82		inner: Option<Box<Error>>,
83	},
84	Rollback {
85		rollbacks: RollbackRecord,
86	},
87}
88
89impl error::Error for Error {
90	fn description(&self) -> &'static str {
91		"Parse error"
92	}
93}
94
95impl Display for Error {
96	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97		match self {
98			Error::Incomplete => write!(f, "Incomplete"),
99			Error::Mismatch {
100				ref message,
101				ref position,
102				continuation_error: None,
103			} => write!(f, "Mismatch at {}: {}", position, message),
104			Error::Mismatch {
105				ref message,
106				ref position,
107				continuation_error: Some(ref continuation_error),
108			} => write!(
109				f,
110				"Mismatch at {}: {}, (cont. error: {})",
111				position, message, continuation_error
112			),
113			Error::Conversion {
114				ref message,
115				ref position,
116			} => write!(f, "Conversion failed at {}: {}", position, message),
117			Error::Expect {
118				ref message,
119				ref position,
120				ref inner,
121			} => write!(f, "{} at {}: {}", message, position, inner),
122			Error::Custom {
123				ref message,
124				ref position,
125				inner: Some(ref inner),
126			} => write!(f, "{} at {}, (inner: {})", message, position, inner),
127			Error::Custom {
128				ref message,
129				ref position,
130				inner: None,
131			} => write!(f, "{} at {}", message, position),
132			Error::Rollback { ref rollbacks } => {
133				writeln!(f, "Rollback log:")?;
134				write!(f, "{}", rollbacks)?;
135				Ok(())
136			}
137		}
138	}
139}
140
141/// Parser result, `Result<O>` ia alias of `Result<O, pom::Error>`.
142pub type Result<O> = ::std::result::Result<O, Error>;