• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::fs::{PathBuf, PathError};
2 use alloc::string::FromUtf8Error;
3 use core::fmt::{self, Debug, Display, Formatter};
4 
5 /// All errors that can happen when working with the [`FileSystem`].
6 ///
7 /// [`FileSystem`]: super::FileSystem
8 #[derive(Debug, Clone, PartialEq, Eq)]
9 pub enum Error {
10     /// IO (low-level UEFI-errors) errors. See [`IoError`].
11     Io(IoError),
12     /// Path-related errors. See [`PathError`].
13     Path(PathError),
14     /// Can't parse file content as UTF-8. See [`FromUtf8Error`].
15     Utf8Encoding(FromUtf8Error),
16 }
17 
18 impl Display for Error {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result19     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
20         match self {
21             Self::Io(_) => write!(f, "IO error"),
22             Self::Path(_) => write!(f, "path error"),
23             Self::Utf8Encoding(_) => write!(f, "UTF-8 encoding error"),
24         }
25     }
26 }
27 
28 /// UEFI-error with context when working with the underlying UEFI file protocol.
29 #[derive(Debug, Clone, PartialEq, Eq)]
30 pub struct IoError {
31     /// The path that led to the error.
32     pub path: PathBuf,
33     /// The context in which the path was used.
34     pub context: IoErrorContext,
35     /// The underlying UEFI error.
36     pub uefi_error: crate::Error,
37 }
38 
39 impl Display for IoError {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result40     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
41         write!(f, "IO error for path {}: {}", self.path, self.context)
42     }
43 }
44 
45 /// Enum that further specifies the context in that an [`Error`] occurred.
46 #[derive(Debug, Clone, PartialEq, Eq)]
47 pub enum IoErrorContext {
48     /// Can't delete the directory.
49     CantDeleteDirectory,
50     /// Can't delete the file.
51     CantDeleteFile,
52     /// Error flushing file.
53     FlushFailure,
54     /// Can't open the root directory of the underlying volume.
55     CantOpenVolume,
56     /// Error while reading the metadata of the file.
57     Metadata,
58     /// Could not open the given path. One possible reason is that the file does
59     /// not exist.
60     OpenError,
61     /// Error reading file.
62     ReadFailure,
63     /// Error writing bytes.
64     WriteFailure,
65     /// The path exists but does not correspond to a directory when a directory
66     /// was expected.
67     NotADirectory,
68     /// The path exists but does not correspond to a file when a file was
69     /// expected.
70     NotAFile,
71 }
72 
73 impl Display for IoErrorContext {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result74     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
75         let s = match self {
76             Self::CantDeleteDirectory => "failed to delete directory",
77             Self::CantDeleteFile => "failed to delete file",
78             Self::FlushFailure => "failed to flush file",
79             Self::CantOpenVolume => "failed to open volume",
80             Self::Metadata => "failed to read metadata",
81             Self::OpenError => "failed to open file",
82             Self::ReadFailure => "failed to read file",
83             Self::WriteFailure => "failed to write file",
84             Self::NotADirectory => "expected a directory",
85             Self::NotAFile => "expected a file",
86         };
87         write!(f, "{s}")
88     }
89 }
90 
91 impl From<PathError> for Error {
from(value: PathError) -> Self92     fn from(value: PathError) -> Self {
93         Self::Path(value)
94     }
95 }
96 
97 #[cfg(feature = "unstable")]
98 impl core::error::Error for Error {
source(&self) -> Option<&(dyn core::error::Error + 'static)>99     fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
100         match self {
101             Error::Io(err) => Some(err),
102             Error::Path(err) => Some(err),
103             Error::Utf8Encoding(err) => Some(err),
104         }
105     }
106 }
107 
108 #[cfg(feature = "unstable")]
109 impl core::error::Error for IoError {
source(&self) -> Option<&(dyn core::error::Error + 'static)>110     fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
111         Some(&self.uefi_error)
112     }
113 }
114