Skip to content

Commit

Permalink
rust: error: add From implementations for Error
Browse files Browse the repository at this point in the history
Add a set of `From` implementations for the `Error` kernel type.

These implementations allow to easily convert from standard Rust
error types to the usual kernel errors based on one of the `E*`
integer codes.

On top of that, the question mark Rust operator (`?`) implicitly
performs a conversion on the error value using the `From` trait
when propagating. Thus it is extra convenient to use.

For instance, a kernel function that needs to convert a `i64` into
a `i32` and to bubble up the error as a kernel error may write:

    fn f(x: i64) -> Result<...> {
        ...
        let y = i32::try_from(x)?;
        ...
    }

which will transform the `TryFromIntError` into an `Err(EINVAL)`.

Co-developed-by: Adam Bratschi-Kaye <[email protected]>
Signed-off-by: Adam Bratschi-Kaye <[email protected]>
Co-developed-by: Nándor István Krácser <[email protected]>
Signed-off-by: Nándor István Krácser <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Reviewed-by: Finn Behrens <[email protected]>
[Reworded, adapted for upstream and applied latest changes]
Signed-off-by: Miguel Ojeda <[email protected]>
  • Loading branch information
wedsonaf authored and ojeda committed Dec 4, 2022
1 parent 266def2 commit 76e2c2d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
45 changes: 44 additions & 1 deletion rust/kernel/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
//!
//! C header: [`include/uapi/asm-generic/errno-base.h`](../../../include/uapi/asm-generic/errno-base.h)

use alloc::collections::TryReserveError;
use alloc::{
alloc::{AllocError, LayoutError},
collections::TryReserveError,
};

use core::convert::From;
use core::num::TryFromIntError;
use core::str::Utf8Error;

/// Contains the C-compatible error codes.
pub mod code {
Expand Down Expand Up @@ -71,12 +78,48 @@ impl Error {
}
}

impl From<AllocError> for Error {
fn from(_: AllocError) -> Error {
code::ENOMEM
}
}

impl From<TryFromIntError> for Error {
fn from(_: TryFromIntError) -> Error {
code::EINVAL
}
}

impl From<Utf8Error> for Error {
fn from(_: Utf8Error) -> Error {
code::EINVAL
}
}

impl From<TryReserveError> for Error {
fn from(_: TryReserveError) -> Error {
code::ENOMEM
}
}

impl From<LayoutError> for Error {
fn from(_: LayoutError) -> Error {
code::ENOMEM
}
}

impl From<core::fmt::Error> for Error {
fn from(_: core::fmt::Error) -> Error {
code::EINVAL
}
}

impl From<core::convert::Infallible> for Error {
fn from(e: core::convert::Infallible) -> Error {
match e {}
}
}

/// A [`Result`] with an [`Error`] error type.
///
/// To be used as the return type for functions that may fail.
Expand Down
1 change: 1 addition & 0 deletions rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! do so first instead of bypassing this crate.

#![no_std]
#![feature(allocator_api)]
#![feature(core_ffi_c)]

// Ensure conditional compilation based on the kernel configuration works;
Expand Down

0 comments on commit 76e2c2d

Please sign in to comment.