use std::
{
fmt,
io,
path::PathBuf,
};
pub type Result< T > = core::result::Result< T, Error >;
#[derive( Debug )]
pub enum Error
{
Io
{
source : io::Error,
context : String,
},
Parse
{
line : usize,
content : String,
reason : String,
},
PathEncoding
{
path : String,
reason : String,
},
ProjectNotFound
{
id : String,
},
SessionNotFound
{
id : String,
},
InvalidStructure
{
path : PathBuf,
reason : String,
},
WriteFailed
{
target : String,
reason : String,
},
}
impl fmt::Display for Error
{
#[inline]
fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
{
match self
{
Error::Io { source, context } =>
write!( f, "I/O error during {context}: {source}" ),
Error::Parse { line, content, reason } =>
write!
(
f,
"JSONL parse error at line {line}: {reason} (content: {content})"
),
Error::PathEncoding { path, reason } =>
write!( f, "Path encoding error for '{path}': {reason}" ),
Error::ProjectNotFound { id } =>
write!( f, "Project not found: {id}" ),
Error::SessionNotFound { id } =>
write!( f, "Session not found: {id}" ),
Error::InvalidStructure { path, reason } =>
write!( f, "Invalid storage structure at {}: {reason}", path.display() ),
Error::WriteFailed { target, reason } =>
write!( f, "Write failed for {target}: {reason}" ),
}
}
}
impl core::error::Error for Error
{
#[inline]
fn source( &self ) -> Option< &( dyn core::error::Error + 'static ) >
{
match self
{
Error::Io { source, .. } => Some( source ),
_ => None,
}
}
}
impl From< io::Error > for Error
{
#[inline]
fn from( err : io::Error ) -> Self
{
Error::Io
{
source : err,
context : "unknown operation".into(),
}
}
}
impl From< crate::json::JsonError > for Error
{
#[inline]
fn from( err : crate::json::JsonError ) -> Self
{
Error::Parse
{
line : 0,
content : String::new(),
reason : err.message,
}
}
}
impl Error
{
#[inline]
pub fn io< S : Into< String > >( source : io::Error, context : S ) -> Self
{
Error::Io
{
source,
context : context.into(),
}
}
#[inline]
pub fn parse< S : Into< String > >( line : usize, content : S, reason : S ) -> Self
{
Error::Parse
{
line,
content : content.into(),
reason : reason.into(),
}
}
#[inline]
pub fn path_encoding< S : Into< String > >( path : S, reason : S ) -> Self
{
Error::PathEncoding
{
path : path.into(),
reason : reason.into(),
}
}
#[inline]
pub fn project_not_found< S : Into< String > >( id : S ) -> Self
{
Error::ProjectNotFound
{
id : id.into(),
}
}
#[inline]
pub fn session_not_found< S : Into< String > >( id : S ) -> Self
{
Error::SessionNotFound
{
id : id.into(),
}
}
#[inline]
pub fn invalid_structure< S : Into< String > >( path : PathBuf, reason : S ) -> Self
{
Error::InvalidStructure
{
path,
reason : reason.into(),
}
}
#[inline]
pub fn write_failed< S : Into< String > >( target : S, reason : S ) -> Self
{
Error::WriteFailed
{
target : target.into(),
reason : reason.into(),
}
}
}