You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.3 KiB
110 lines
2.3 KiB
//! Config parsing error
|
|
use super::*;
|
|
use std::{
|
|
io,
|
|
path::PathBuf,
|
|
};
|
|
|
|
|
|
//TODO: Embed info about the file, the line number, the expression, etc?
|
|
/// Error type for parsing config errors
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
|
|
/// Internal IO error
|
|
IO(io::Error),
|
|
/// S-expression syntax error
|
|
Syntax(sexp::Error),
|
|
|
|
/// File not found, or was a directory
|
|
NotFound(PathBuf),
|
|
/// File contained invalid UTF-8
|
|
InvalidUtf8,
|
|
/// Invalid or unexpected type
|
|
TypeError{expected:LispType, got: LispType},
|
|
/// Expected a list with at least one element
|
|
UnexpectedEmpty,
|
|
|
|
/// Unknown definition string
|
|
UnknownDefinition(String),
|
|
|
|
/// Non-descript other error
|
|
Unknown,
|
|
}
|
|
|
|
impl Error
|
|
{
|
|
/// Helper function for type errors
|
|
#[inline]
|
|
pub fn bad_type<T,U>(expected: T, got: U) -> Self
|
|
where T: Into<LispType>,
|
|
U: Into<LispType>
|
|
{
|
|
Self::TypeError {
|
|
expected: expected.into(),
|
|
got: got.into()
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for Error
|
|
{
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)>
|
|
{
|
|
Some(match &self {
|
|
Self::IO(io) => io,
|
|
Self::Syntax(sy) => sy,
|
|
_ => return None,
|
|
})
|
|
}
|
|
}
|
|
impl std::fmt::Display for Error
|
|
{
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
|
{
|
|
match self {
|
|
Self::IO(io) => write!(f, "i/o error: {}", io),
|
|
Self::Syntax(sy) => write!(f, "s-expression syntax error: {}", sy),
|
|
Self::NotFound(path) => write!(f, "File not found: {:?}", path),
|
|
Self::InvalidUtf8 => write!(f, "Invalid UTF8 decoded string or some such"),
|
|
Self::TypeError{expected, got} => write!(f, "Type mismatch: Expected {}, got {}", expected, got),
|
|
Self::UnexpectedEmpty => write!(f, "expected a non-empty list"),
|
|
Self::UnknownDefinition(def) => write!(f, "unknown definition `{}'", def),
|
|
|
|
_ => write!(f, "unknown error")
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<io::Error> for Error
|
|
{
|
|
fn from(from: io::Error) -> Self
|
|
{
|
|
Self::IO(from)
|
|
}
|
|
}
|
|
|
|
impl From<sexp::Error> for Error
|
|
{
|
|
fn from(from: sexp::Error) -> Self
|
|
{
|
|
Self::Syntax(from)
|
|
}
|
|
}
|
|
|
|
impl From<Box<sexp::Error>> for Error
|
|
{
|
|
fn from(from: Box<sexp::Error>) -> Self
|
|
{
|
|
Self::Syntax(*from)
|
|
}
|
|
}
|
|
|
|
impl From<std::str::Utf8Error> for Error
|
|
{
|
|
fn from(_: std::str::Utf8Error) -> Self
|
|
{
|
|
Self::InvalidUtf8
|
|
}
|
|
}
|