Skip to content

Commit

Permalink
Use constants for error codes
Browse files Browse the repository at this point in the history
This makes it possible to de-couple the error codes from littlefs2-sys
once we move the error types into littlefs2-core.
  • Loading branch information
robin-nitrokey committed Jul 3, 2024
1 parent a47ed53 commit d791cb4
Showing 1 changed file with 55 additions and 40 deletions.
95 changes: 55 additions & 40 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,25 @@ pub struct Error {
}

impl Error {
const IO: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_IO }>();
const CORRUPT: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_CORRUPT }>();
const NOENT: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NOENT }>();
const EXIST: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_EXIST }>();
const NOTDIR: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NOTDIR }>();
const ISDIR: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_ISDIR }>();
const NOTEMPTY: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NOTEMPTY }>();
const BADF: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_BADF }>();
const FBIG: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_FBIG }>();
const INVAL: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_INVAL }>();
const NOSPC: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NOSPC }>();
const NOMEM: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NOMEM }>();
const NOATTR: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NOATTR }>();
const NAMETOOLONG: Self = Self::new_const::<{ ll::lfs_error_LFS_ERR_NAMETOOLONG }>();

/// Construct an `Error` from an error code.
///
/// Error codes that are greater or equals to zero represent success. In this case, `None` is
/// returned.
/// Return values that are greater or equals to zero represent success. In this case, `None`
/// is returned.
pub const fn new(code: c_int) -> Option<Self> {
if code >= 0 {
None
Expand All @@ -135,28 +150,30 @@ impl Error {
}
}

const fn new_const<const N: i32>() -> Self {
if N >= 0 {
panic!("error code must be negative");
}
Self { code: N }
}

/// Construct an `Error` from an error kind.
pub const fn from_kind(kind: ErrorKind) -> Self {
let code = match kind {
ErrorKind::Io => ll::lfs_error_LFS_ERR_IO,
ErrorKind::Corruption => ll::lfs_error_LFS_ERR_CORRUPT,
ErrorKind::NoSuchEntry => ll::lfs_error_LFS_ERR_NOENT,
ErrorKind::EntryAlreadyExisted => ll::lfs_error_LFS_ERR_EXIST,
ErrorKind::PathNotDir => ll::lfs_error_LFS_ERR_NOTDIR,
ErrorKind::PathIsDir => ll::lfs_error_LFS_ERR_ISDIR,
ErrorKind::DirNotEmpty => ll::lfs_error_LFS_ERR_NOTEMPTY,
ErrorKind::BadFileDescriptor => ll::lfs_error_LFS_ERR_BADF,
ErrorKind::FileTooBig => ll::lfs_error_LFS_ERR_FBIG,
ErrorKind::Invalid => ll::lfs_error_LFS_ERR_INVAL,
ErrorKind::NoSpace => ll::lfs_error_LFS_ERR_NOSPC,
ErrorKind::NoMemory => ll::lfs_error_LFS_ERR_NOMEM,
ErrorKind::NoAttribute => ll::lfs_error_LFS_ERR_NOATTR,
ErrorKind::FilenameTooLong => ll::lfs_error_LFS_ERR_NAMETOOLONG,
};
if let Some(error) = Self::new(code) {
error
} else {
panic!("error code must be negative");
match kind {
ErrorKind::Io => Self::IO,
ErrorKind::Corruption => Self::CORRUPT,
ErrorKind::NoSuchEntry => Self::NOENT,
ErrorKind::EntryAlreadyExisted => Self::EXIST,
ErrorKind::PathNotDir => Self::NOTDIR,
ErrorKind::PathIsDir => Self::ISDIR,
ErrorKind::DirNotEmpty => Self::NOTEMPTY,
ErrorKind::BadFileDescriptor => Self::BADF,
ErrorKind::FileTooBig => Self::FBIG,
ErrorKind::Invalid => Self::INVAL,
ErrorKind::NoSpace => Self::NOSPC,
ErrorKind::NoMemory => Self::NOMEM,
ErrorKind::NoAttribute => Self::NOATTR,
ErrorKind::FilenameTooLong => Self::NAMETOOLONG,
}
}

Expand All @@ -171,27 +188,25 @@ impl Error {
/// adding variants is not considered a breaking change. Therefore, users must not rely on
/// this method returning `None`.
pub const fn kind(&self) -> Option<ErrorKind> {
let kind = match self.code {
ll::lfs_error_LFS_ERR_IO => ErrorKind::Io,
ll::lfs_error_LFS_ERR_CORRUPT => ErrorKind::Corruption,
ll::lfs_error_LFS_ERR_NOENT => ErrorKind::NoSuchEntry,
ll::lfs_error_LFS_ERR_EXIST => ErrorKind::EntryAlreadyExisted,
ll::lfs_error_LFS_ERR_NOTDIR => ErrorKind::PathNotDir,
ll::lfs_error_LFS_ERR_ISDIR => ErrorKind::PathIsDir,
ll::lfs_error_LFS_ERR_NOTEMPTY => ErrorKind::DirNotEmpty,
ll::lfs_error_LFS_ERR_BADF => ErrorKind::BadFileDescriptor,
ll::lfs_error_LFS_ERR_FBIG => ErrorKind::FileTooBig,
ll::lfs_error_LFS_ERR_INVAL => ErrorKind::Invalid,
ll::lfs_error_LFS_ERR_NOSPC => ErrorKind::NoSpace,
ll::lfs_error_LFS_ERR_NOMEM => ErrorKind::NoMemory,
ll::lfs_error_LFS_ERR_NOATTR => ErrorKind::NoAttribute,
ll::lfs_error_LFS_ERR_NAMETOOLONG => ErrorKind::FilenameTooLong,
// positive codes should always indicate success
Some(match *self {
Self::IO => ErrorKind::Io,
Self::CORRUPT => ErrorKind::Corruption,
Self::NOENT => ErrorKind::NoSuchEntry,
Self::EXIST => ErrorKind::EntryAlreadyExisted,
Self::NOTDIR => ErrorKind::PathNotDir,
Self::ISDIR => ErrorKind::PathIsDir,
Self::NOTEMPTY => ErrorKind::DirNotEmpty,
Self::BADF => ErrorKind::BadFileDescriptor,
Self::FBIG => ErrorKind::FileTooBig,
Self::INVAL => ErrorKind::Invalid,
Self::NOSPC => ErrorKind::NoSpace,
Self::NOMEM => ErrorKind::NoMemory,
Self::NOATTR => ErrorKind::NoAttribute,
Self::NAMETOOLONG => ErrorKind::FilenameTooLong,
_ => {
return None;
}
};
Some(kind)
})
}
}

Expand Down

0 comments on commit d791cb4

Please sign in to comment.