use std::error;
use std::fmt;
use std::io;
use std::path::PathBuf;
use std::result;
use std::sync::Arc;
use crate::ctrlc;
use crate::curl;
use crate::serde_json;
use crate::toml;
use crate::matrix;
use crate::pkg::PkgName;
use crate::value::Value;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Pos
{
pub path: Arc<String>,
pub line: u64,
pub column: usize,
}
impl Pos
{
pub fn new(path: Arc<String>, line: u64, column: usize) -> Self
{ Pos { path, line, column, } }
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum ParserEofFlag
{
NoRepetition,
Repetition,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum PkgPathConflict
{
Bin,
Lib,
Doc,
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum Stop
{
Break,
Continue,
Return,
Quit,
ErrorPropagation,
Exit(i32),
}
#[derive(Debug)]
pub enum Error
{
ParserIo(Arc<String>, io::Error),
ParserEof(Arc<String>, ParserEofFlag),
Parser(Pos, String),
Interp(String),
Pkg(String),
PkgName(PkgName, String),
PkgDepCycle(Vec<PkgName>),
PkgPathConflicts(PkgName, Option<PkgName>, Vec<PathBuf>, PkgPathConflict),
Tester(String),
Matrix(matrix::Error),
Mutex,
RwLockRead,
RwLockWrite,
Recv,
AlreadyAddedModNode,
NoFunMod,
NoDocMod,
Io(io::Error),
Ctrlc(ctrlc::Error),
TomlDe(toml::de::Error),
TomlSer(toml::ser::Error),
Winit(Box<dyn error::Error>),
Jammdb(Box<dyn error::Error>),
Zip(Box<dyn error::Error>),
Curl(curl::Error),
SerdeJson(serde_json::Error),
Latex2mathml(Box<dyn error::Error>),
Markdown(String),
Opener(Box<dyn error::Error>),
InvalidVersion,
InvalidPkgName,
NoOpenClBackend,
NoCudaBackend,
Stop(Stop),
Intr,
Assert(Option<String>, Option<(Value, Value)>),
}
impl error::Error for Error
{}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
Error::ParserIo(path, err) => write!(f, "{}: i/o error: {}", path, err),
Error::ParserEof(path, _) => write!(f, "{}: end of file", path),
Error::Parser(pos, msg) => write!(f, "{}: {}.{}: {}", pos.path, pos.line, pos.column, msg),
Error::Interp(msg) => write!(f, "{}", msg),
Error::Pkg(msg) => write!(f, "{}", msg),
Error::PkgName(name, msg) => write!(f, "{}: {}", name, msg),
Error::PkgDepCycle(names) => {
write!(f, "occurred cycle of dependencies: ")?;
let mut is_first = true;
for name in names {
if !is_first {
write!(f, " -> ")?;
}
write!(f, "{}", name)?;
is_first = false;
}
Ok(())
},
Error::PkgPathConflicts(name, name2, conflict_paths, conflict) => {
let conflict_name = match conflict {
PkgPathConflict::Bin => "bin",
PkgPathConflict::Lib => "lib",
PkgPathConflict::Doc => "doc",
};
match name2 {
Some(name2) => write!(f, "occurred conflicts between {} and {} for directory {}:", name, name2, conflict_name)?,
None => write!(f, "occurred conflicts between {} and installed packages for directory {}:", name, conflict_name)?,
}
for conflict_path in conflict_paths {
write!(f, "\n{}", conflict_path.to_string_lossy().into_owned())?;
}
Ok(())
},
Error::Tester(msg) => write!(f, "{}", msg),
Error::Matrix(err) => write!(f, "matrix error: {}", err),
Error::Mutex => write!(f, "can't lock mutex"),
Error::RwLockRead => write!(f, "can't read rw lock"),
Error::RwLockWrite => write!(f, "can't write rw lock"),
Error::Recv => write!(f, "can't receive object"),
Error::AlreadyAddedModNode => write!(f, "already added module node"),
Error::NoFunMod => write!(f, "no function module"),
Error::NoDocMod => write!(f, "no documentation module"),
Error::Io(err) => write!(f, "i/o error: {}", err),
Error::Ctrlc(err) => write!(f, "ctrl-c error: {}", err),
Error::TomlDe(err) => write!(f, "toml error: {}", err),
Error::TomlSer(err) => write!(f, "toml error: {}", err),
Error::Winit(err) => write!(f, "winit error: {}", err),
Error::Jammdb(err) => write!(f, "jammdb error: {}", err),
Error::Zip(err) => write!(f, "zip error: {}", err),
Error::Curl(err) => write!(f, "curl error: {}", err),
Error::SerdeJson(err) => write!(f, "serde_json error: {}", err),
Error::Latex2mathml(err) => write!(f, "latex2mathml error: {}", err),
Error::Markdown(msg) => write!(f, "markdown error: {}", msg),
Error::Opener(err) => write!(f, "opener error: {}", err),
Error::InvalidVersion => write!(f, "invalid version"),
Error::InvalidPkgName => write!(f, "invalid package name"),
Error::NoOpenClBackend => write!(f, "no OpenCL backend"),
Error::NoCudaBackend => write!(f, "no CUDA backend"),
Error::Stop(Stop::Break) => write!(f, "stopped by break"),
Error::Stop(Stop::Continue) => write!(f, "stopped by continue"),
Error::Stop(Stop::Return) => write!(f, "stopped by return"),
Error::Stop(Stop::Quit) => write!(f, "stopped by quit"),
Error::Stop(Stop::ErrorPropagation) => write!(f, "stopped by error propagation"),
Error::Stop(Stop::Exit(code)) => write!(f, "stopped by exit with code {}", code),
Error::Intr => write!(f, "interrupted"),
Error::Assert(msg, pair) => {
match msg {
Some(msg) => write!(f, "assertion failed: {}", msg)?,
None => write!(f, "assertion failed")?,
}
match pair {
Some((left, right)) => {
write!(f, "\nleft: {}", left)?;
write!(f, "\nright: {}", right)?;
},
None => (),
}
Ok(())
},
}
}
}
pub type Result<T> = result::Result<T, Error>;