ucglib/build/opcode/
error.rs1use std::convert::From;
15use std::fmt;
16use std::fmt::Display;
17use std::io;
18use std::rc::Rc;
19
20use crate::ast::Position;
21use crate::build::opcode::convert;
22
23#[derive(Debug)]
24pub struct Error {
25 message: Rc<str>,
26 pos: Option<Position>,
27 call_stack: Vec<Position>,
28}
29
30impl Error {
31 pub fn new(msg: Rc<str>, pos: Position) -> Self {
32 Self {
33 message: msg,
34 pos: Some(pos),
35 call_stack: Vec::new(),
36 }
37 }
38
39 pub fn with_pos(mut self, pos: Position) -> Self {
40 self.pos = Some(pos);
41 self
42 }
43
44 pub fn push_call_stack(&mut self, pos: Position) {
45 self.call_stack.push(pos);
46 }
47}
48
49macro_rules! decorate_error {
50 ($pos:expr => $result:expr) => {
51 match $result {
52 Ok(v) => Ok(v),
53 Err(e) => Err(e.with_pos($pos.clone())),
54 }
55 };
56}
57
58macro_rules! decorate_call {
59 ($pos:expr => $result:expr) => {
60 match $result {
61 Ok(v) => Ok(v),
62 Err(mut e) => {
63 e.push_call_stack($pos.clone());
64 Err(e)
65 }
66 }
67 };
68}
69
70impl From<regex::Error> for Error {
71 fn from(e: regex::Error) -> Self {
72 Error {
73 message: format!("{}", e).into(),
74 pos: None,
75 call_stack: Vec::new(),
76 }
77 }
78}
79
80impl From<std::io::Error> for Error {
81 fn from(e: std::io::Error) -> Self {
82 let msg = match e.kind() {
83 io::ErrorKind::NotFound | io::ErrorKind::Other => {
84 format!("OSError: Path not found: {}", e)
85 }
86 _ => format!("{}", e),
87 }
88 .into();
89 Error {
90 message: msg,
91 pos: None,
92 call_stack: Vec::new(),
93 }
94 }
95}
96
97impl From<convert::Error> for Error {
98 fn from(e: convert::Error) -> Self {
99 Error {
100 message: e.message().into(),
101 pos: None,
102 call_stack: Vec::new(),
103 }
104 }
105}
106
107impl Display for Error {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 if let Some(ref pos) = self.pos {
110 write!(f, "{} at {}", self.message, pos)?;
111 } else {
112 write!(f, "{}", self.message)?;
113 }
114 if !self.call_stack.is_empty() {
115 for p in self.call_stack.iter() {
116 write!(f, "\nVIA: {}", p)?;
117 }
118 }
119 Ok(())
120 }
121}
122
123impl std::error::Error for Error {}