diff --git a/awkernel_lib/src/file/vfs.rs b/awkernel_lib/src/file/vfs.rs new file mode 100644 index 000000000..a91e73517 --- /dev/null +++ b/awkernel_lib/src/file/vfs.rs @@ -0,0 +1 @@ +pub mod error; diff --git a/awkernel_lib/src/file/vfs/error.rs b/awkernel_lib/src/file/vfs/error.rs index 5e96a9eb8..981e6acf1 100644 --- a/awkernel_lib/src/file/vfs/error.rs +++ b/awkernel_lib/src/file/vfs/error.rs @@ -1,43 +1,34 @@ //! Error and Result definitions -use std::{error, fmt, io}; +use super::super::error::IoError; +use super::super::fatfs::error::Error as FatfsError; +use alloc::{ + boxed::Box, + string::{String, ToString}, +}; +use core::fmt; /// The error type of this crate #[derive(Debug)] -pub struct VfsError { +pub struct VfsError { /// The path this error was encountered in path: String, /// The kind of error - kind: VfsErrorKind, + kind: VfsErrorKind, /// An optional human-readable string describing the context for this error /// /// If not provided, a generic context message is used context: String, /// The underlying error - cause: Option>, + cause: Option>>, } /// The only way to create a VfsError is via a VfsErrorKind /// /// This conversion implements certain normalizations -impl From for VfsError { - fn from(kind: VfsErrorKind) -> Self { - // Normalize the error here before we return it - let kind = match kind { - VfsErrorKind::IoError(io) => match io.kind() { - io::ErrorKind::NotFound => VfsErrorKind::FileNotFound, - // TODO: If MSRV changes to 1.53, enable this. Alternatively, - // if it's possible to #[cfg] just this line, try that - // io::ErrorKind::Unsupported => VfsErrorKind::NotSupported, - _ => VfsErrorKind::IoError(io), - }, - // Remaining kinda are passed through as-is - other => other, - }; - +impl From> for VfsError { + fn from(kind: VfsErrorKind) -> Self { Self { - // TODO (Techno): See if this could be checked at compile-time to make sure the VFS abstraction - // never forgets to add a path. Might need a separate error type for FS impls vs VFS path: "PATH NOT FILLED BY VFS LAYER".into(), kind, context: "An error occured".into(), @@ -46,15 +37,9 @@ impl From for VfsError { } } -impl From for VfsError { - fn from(err: io::Error) -> Self { - Self::from(VfsErrorKind::IoError(err)) - } -} - -impl VfsError { +impl VfsError { // Path filled by the VFS crate rather than the implementations - pub(crate) fn with_path(mut self, path: impl Into) -> Self { + pub fn with_path(mut self, path: impl Into) -> Self { self.path = path.into(); self } @@ -68,12 +53,12 @@ impl VfsError { self } - pub fn with_cause(mut self, cause: VfsError) -> Self { + pub fn with_cause(mut self, cause: VfsError) -> Self { self.cause = Some(Box::new(cause)); self } - pub fn kind(&self) -> &VfsErrorKind { + pub fn kind(&self) -> &VfsErrorKind { &self.kind } @@ -82,33 +67,19 @@ impl VfsError { } } -impl fmt::Display for VfsError { +impl fmt::Display for VfsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} for '{}': {}", self.context, self.path, self.kind()) } } -impl error::Error for VfsError { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - if let Some(cause) = &self.cause { - Some(cause) - } else { - None - } - } -} - /// The kinds of errors that can occur #[derive(Debug)] -pub enum VfsErrorKind { +pub enum VfsErrorKind { /// A generic I/O error /// /// Certain standard I/O errors are normalized to their VfsErrorKind counterparts - IoError(io::Error), - - #[cfg(feature = "async-vfs")] - /// A generic async I/O error - AsyncIoError(io::Error), + IoError(E), /// The file or directory at the given path could not be found FileNotFound, @@ -129,15 +100,11 @@ pub enum VfsErrorKind { NotSupported, } -impl fmt::Display for VfsErrorKind { +impl fmt::Display for VfsErrorKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { VfsErrorKind::IoError(cause) => { - write!(f, "IO error: {}", cause) - } - #[cfg(feature = "async-vfs")] - VfsErrorKind::AsyncIoError(cause) => { - write!(f, "Async IO error: {}", cause) + write!(f, "IO error: {cause}") } VfsErrorKind::FileNotFound => { write!(f, "The file or directory could not be found") @@ -146,7 +113,7 @@ impl fmt::Display for VfsErrorKind { write!(f, "The path is invalid") } VfsErrorKind::Other(message) => { - write!(f, "FileSystem error: {}", message) + write!(f, "FileSystem error: {message}") } VfsErrorKind::NotSupported => { write!(f, "Functionality not supported by this filesystem") @@ -162,27 +129,4 @@ impl fmt::Display for VfsErrorKind { } /// The result type of this crate -pub type VfsResult = std::result::Result; - -#[cfg(test)] -mod tests { - use crate::error::VfsErrorKind; - use crate::{VfsError, VfsResult}; - - fn produce_vfs_result() -> VfsResult<()> { - Err(VfsError::from(VfsErrorKind::Other("Not a file".into())).with_path("foo")) - } - - fn produce_anyhow_result() -> anyhow::Result<()> { - Ok(produce_vfs_result()?) - } - - #[test] - fn anyhow_compatibility() { - let result = produce_anyhow_result().unwrap_err(); - assert_eq!( - result.to_string(), - "An error occured for 'foo': FileSystem error: Not a file" - ) - } -} +pub type VfsResult = core::result::Result>;