1use std::error;
10use std::fmt;
11use std::io;
12use std::path::PathBuf;
13use std::result;
14use std::sync::Arc;
15use crate::ctrlc;
16use crate::curl;
17use crate::serde_json;
18use crate::toml;
19use crate::matrix;
20use crate::pkg::PkgName;
21use crate::value::Value;
22
23#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
25pub struct Pos
26{
27 pub path: Arc<String>,
29 pub line: u64,
31 pub column: usize,
33}
34
35impl Pos
36{
37 pub fn new(path: Arc<String>, line: u64, column: usize) -> Self
39 { Pos { path, line, column, } }
40}
41
42#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
47pub enum ParserEofFlag
48{
49 NoRepetition,
51 Repetition,
53}
54
55#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
57pub enum PkgPathConflict
58{
59 Bin,
61 Lib,
63 Doc,
65}
66
67#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
69pub enum Stop
70{
71 Break,
73 Continue,
75 Return,
77 Quit,
79 ErrorPropagation,
81 Exit(i32),
83}
84
85#[derive(Debug)]
87pub enum Error
88{
89 ParserIo(Arc<String>, io::Error),
91 ParserEof(Arc<String>, ParserEofFlag),
93 Parser(Pos, String),
95 Interp(String),
97 Pkg(String),
99 PkgName(PkgName, String),
101 PkgDepCycle(Vec<PkgName>),
103 PkgPathConflicts(PkgName, Option<PkgName>, Vec<PathBuf>, PkgPathConflict),
105 Tester(String),
107 Matrix(matrix::Error),
109 Mutex,
111 RwLockRead,
113 RwLockWrite,
115 Recv,
117 AlreadyAddedModNode,
119 NoFunMod,
121 NoDocMod,
123 Io(io::Error),
125 Ctrlc(ctrlc::Error),
127 TomlDe(toml::de::Error),
129 TomlSer(toml::ser::Error),
131 Winit(Box<dyn error::Error>),
133 Jammdb(Box<dyn error::Error>),
135 Zip(Box<dyn error::Error>),
137 Curl(curl::Error),
139 SerdeJson(serde_json::Error),
141 Latex2mathml(Box<dyn error::Error>),
143 Markdown(String),
145 Opener(Box<dyn error::Error>),
147 InvalidVersion,
149 InvalidPkgName,
151 NoOpenClBackend,
153 NoCudaBackend,
155 Stop(Stop),
157 Intr,
159 Assert(Option<String>, Option<(Value, Value)>),
161}
162
163impl error::Error for Error
164{}
165
166impl fmt::Display for Error
167{
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
169 {
170 match self {
171 Error::ParserIo(path, err) => write!(f, "{}: i/o error: {}", path, err),
172 Error::ParserEof(path, _) => write!(f, "{}: end of file", path),
173 Error::Parser(pos, msg) => write!(f, "{}: {}.{}: {}", pos.path, pos.line, pos.column, msg),
174 Error::Interp(msg) => write!(f, "{}", msg),
175 Error::Pkg(msg) => write!(f, "{}", msg),
176 Error::PkgName(name, msg) => write!(f, "{}: {}", name, msg),
177 Error::PkgDepCycle(names) => {
178 write!(f, "occurred cycle of dependencies: ")?;
179 let mut is_first = true;
180 for name in names {
181 if !is_first {
182 write!(f, " -> ")?;
183 }
184 write!(f, "{}", name)?;
185 is_first = false;
186 }
187 Ok(())
188 },
189 Error::PkgPathConflicts(name, name2, conflict_paths, conflict) => {
190 let conflict_name = match conflict {
191 PkgPathConflict::Bin => "bin",
192 PkgPathConflict::Lib => "lib",
193 PkgPathConflict::Doc => "doc",
194 };
195 match name2 {
196 Some(name2) => write!(f, "occurred conflicts between {} and {} for directory {}:", name, name2, conflict_name)?,
197 None => write!(f, "occurred conflicts between {} and installed packages for directory {}:", name, conflict_name)?,
198 }
199 for conflict_path in conflict_paths {
200 write!(f, "\n{}", conflict_path.to_string_lossy().into_owned())?;
201 }
202 Ok(())
203 },
204 Error::Tester(msg) => write!(f, "{}", msg),
205 Error::Matrix(err) => write!(f, "matrix error: {}", err),
206 Error::Mutex => write!(f, "can't lock mutex"),
207 Error::RwLockRead => write!(f, "can't read rw lock"),
208 Error::RwLockWrite => write!(f, "can't write rw lock"),
209 Error::Recv => write!(f, "can't receive object"),
210 Error::AlreadyAddedModNode => write!(f, "already added module node"),
211 Error::NoFunMod => write!(f, "no function module"),
212 Error::NoDocMod => write!(f, "no documentation module"),
213 Error::Io(err) => write!(f, "i/o error: {}", err),
214 Error::Ctrlc(err) => write!(f, "ctrl-c error: {}", err),
215 Error::TomlDe(err) => write!(f, "toml error: {}", err),
216 Error::TomlSer(err) => write!(f, "toml error: {}", err),
217 Error::Winit(err) => write!(f, "winit error: {}", err),
218 Error::Jammdb(err) => write!(f, "jammdb error: {}", err),
219 Error::Zip(err) => write!(f, "zip error: {}", err),
220 Error::Curl(err) => write!(f, "curl error: {}", err),
221 Error::SerdeJson(err) => write!(f, "serde_json error: {}", err),
222 Error::Latex2mathml(err) => write!(f, "latex2mathml error: {}", err),
223 Error::Markdown(msg) => write!(f, "markdown error: {}", msg),
224 Error::Opener(err) => write!(f, "opener error: {}", err),
225 Error::InvalidVersion => write!(f, "invalid version"),
226 Error::InvalidPkgName => write!(f, "invalid package name"),
227 Error::NoOpenClBackend => write!(f, "no OpenCL backend"),
228 Error::NoCudaBackend => write!(f, "no CUDA backend"),
229 Error::Stop(Stop::Break) => write!(f, "stopped by break"),
230 Error::Stop(Stop::Continue) => write!(f, "stopped by continue"),
231 Error::Stop(Stop::Return) => write!(f, "stopped by return"),
232 Error::Stop(Stop::Quit) => write!(f, "stopped by quit"),
233 Error::Stop(Stop::ErrorPropagation) => write!(f, "stopped by error propagation"),
234 Error::Stop(Stop::Exit(code)) => write!(f, "stopped by exit with code {}", code),
235 Error::Intr => write!(f, "interrupted"),
236 Error::Assert(msg, pair) => {
237 match msg {
238 Some(msg) => write!(f, "assertion failed: {}", msg)?,
239 None => write!(f, "assertion failed")?,
240 }
241 match pair {
242 Some((left, right)) => {
243 write!(f, "\nleft: {}", left)?;
244 write!(f, "\nright: {}", right)?;
245 },
246 None => (),
247 }
248 Ok(())
249 },
250 }
251 }
252}
253
254pub type Result<T> = result::Result<T, Error>;