Skip to content

Commit

Permalink
Only handle error values in Error and ErrorKind
Browse files Browse the repository at this point in the history
littlefs2 error codes are negative.  Non-negative values indicate
success.  This patch updates our error types to enforce this property by
changing the return type of Error::new to Option<Self> and by removing
ErrorKind::Success.
  • Loading branch information
robin-nitrokey committed Jul 3, 2024
1 parent 1ef30b8 commit a47ed53
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Refactor error types:
- Rename `Error` enum to `ErrorKind` and make it non-exhaustive.
- Add `Error` struct that represents an error code that may or may not map to an `ErrorKind`.
- Remove `ErrorKind::Success` and enforce negative values error codes for `Error`.

### Removed

Expand Down
31 changes: 18 additions & 13 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,20 @@ pub struct Error {

impl Error {
/// Construct an `Error` from an error code.
pub const fn new(code: c_int) -> Self {
Self { code }
///
/// Error codes 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
} else {
Some(Self { code })
}
}

/// Construct an `Error` from an `ErrorKind`.
/// Construct an `Error` from an error kind.
pub const fn from_kind(kind: ErrorKind) -> Self {
let code = match kind {
ErrorKind::Success => ll::lfs_error_LFS_ERR_OK,
ErrorKind::Io => ll::lfs_error_LFS_ERR_IO,
ErrorKind::Corruption => ll::lfs_error_LFS_ERR_CORRUPT,
ErrorKind::NoSuchEntry => ll::lfs_error_LFS_ERR_NOENT,
Expand All @@ -147,7 +153,11 @@ impl Error {
ErrorKind::NoAttribute => ll::lfs_error_LFS_ERR_NOATTR,
ErrorKind::FilenameTooLong => ll::lfs_error_LFS_ERR_NAMETOOLONG,
};
Self::new(code)
if let Some(error) = Self::new(code) {
error
} else {
panic!("error code must be negative");
}
}

/// Return the error code of this error.
Expand All @@ -162,8 +172,6 @@ impl Error {
/// this method returning `None`.
pub const fn kind(&self) -> Option<ErrorKind> {
let kind = match self.code {
n if n >= 0 => ErrorKind::Success,
// negative codes
ll::lfs_error_LFS_ERR_IO => ErrorKind::Io,
ll::lfs_error_LFS_ERR_CORRUPT => ErrorKind::Corruption,
ll::lfs_error_LFS_ERR_NOENT => ErrorKind::NoSuchEntry,
Expand Down Expand Up @@ -203,8 +211,6 @@ impl From<Error> for c_int {
#[derive(Clone, Copy, Debug, PartialEq)]
#[non_exhaustive]
pub enum ErrorKind {
/// Error code was >=0, operation was successful.
Success,
/// Input / output error occurred.
Io,
/// File or filesystem was corrupt.
Expand Down Expand Up @@ -242,10 +248,9 @@ pub fn error_code_from<T>(result: Result<T>) -> ll::lfs_error {
}

pub fn result_from<T>(return_value: T, error_code: ll::lfs_error) -> Result<T> {
let error = Error::new(error_code);
if error.kind() == Some(ErrorKind::Success) {
Ok(return_value)
} else {
if let Some(error) = Error::new(error_code) {
Err(error)
} else {
Ok(return_value)
}
}

0 comments on commit a47ed53

Please sign in to comment.