pencil_puzzles_core/
error.rs1use std::error::Error;
4use std::fmt;
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
8#[non_exhaustive]
9pub enum Position {
10 None,
12 Line(usize),
14 Char(usize),
16}
17
18#[derive(Clone, Debug, PartialEq, Eq, Hash)]
21pub struct ParseError {
22 position: Position,
23 message: String,
24}
25
26impl ParseError {
27 pub fn new(message: impl Into<String>) -> Self {
29 Self {
30 position: Position::None,
31 message: message.into(),
32 }
33 }
34
35 pub fn at_line(line: usize, message: impl Into<String>) -> Self {
37 Self {
38 position: Position::Line(line),
39 message: message.into(),
40 }
41 }
42
43 pub fn at_char(position: usize, message: impl Into<String>) -> Self {
45 Self {
46 position: Position::Char(position),
47 message: message.into(),
48 }
49 }
50
51 pub fn position(&self) -> Position {
53 self.position
54 }
55
56 pub fn message(&self) -> &str {
58 &self.message
59 }
60
61 pub fn or_at_line(self, line: usize) -> Self {
63 match self.position {
64 Position::None => Self::at_line(line, self.message),
65 _ => self,
66 }
67 }
68}
69
70impl fmt::Display for ParseError {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self.position {
73 Position::None => f.write_str(&self.message),
74 Position::Line(line) => write!(f, "line {line}: {}", self.message),
75 Position::Char(position) => write!(f, "character {position}: {}", self.message),
76 }
77 }
78}
79
80impl Error for ParseError {}