//! Config parsing error
use super ::* ;
use std ::{
io ,
path ::PathBuf ,
} ;
//TODO: Embed info about the file, the line number, the expression, etc?
// Will require writing own parser, that embeds such file metadata in its returned expressions. Maybe do this after functionality is implemented for program
/// 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
}
}