From: "Onur Özkan" <work@onurozkan.dev>
To: rust-for-linux@vger.kernel.org
Cc: ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com,
	gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org,
	a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu,
	dakr@kernel.org, tamird@gmail.com
Subject: Re: [PATCH v3 1/2] rust: add `ToResult` trait
Date: Mon, 13 Oct 2025 15:48:19 +0300	[thread overview]
Message-ID: <20251013154819.15149262@nimda.home> (raw)
In-Reply-To: <20251013124139.18809-2-work@onurozkan.dev>
On Mon, 13 Oct 2025 15:41:38 +0300
Onur Özkan <work@onurozkan.dev> wrote:
> Adds `ToResult` trait to handle integer return values from C
> kernel functions.
> 
> Example:
>     let _value = unsafe { bindings::foo() }.to_result()?;
> 
> This will replace the existing `error::to_result` function,
> but it will be handled in the next commit to keep the diff
> more readable.
> 
> Signed-off-by: Onur Özkan <work@onurozkan.dev>
> ---
>  rust/kernel/error.rs | 74
> ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74
> insertions(+)
> 
> diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
> index 1c0e0e241daa..dc566b0cef13 100644
> --- a/rust/kernel/error.rs
> +++ b/rust/kernel/error.rs
> @@ -392,6 +392,80 @@ fn from(e: core::convert::Infallible) -> Error {
>  /// [Rust documentation]:
> https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html
> pub type Result<T = (), E = Error> = core::result::Result<T, E>; 
> +/// Trait for handling integer return values from C kernel functions
> by converting +/// them into idiomatic Rust [`Result`]s.
> +pub trait ToResult {
> +    /// The unsigned version of the integer type used for successful
> return values.
> +    type Unsigned;
> +
> +    /// Converts an integer as returned by a C kernel function to a
> [`Result`].
> +    ///
> +    /// If the integer is negative, an [`Err`] with an [`Error`] as
> given by [`Error::from_errno`]
> +    /// is returned. This means the integer must be `>= -MAX_ERRNO`.
> +    ///
> +    /// Otherwise, it returns the original value as an unsigned
> integer.
> +    ///
> +    /// It is a bug to pass an out-of-range negative integer.
> `Err(EINVAL)` is returned
> +    /// in such a case.
> +    ///
> +    /// # Examples
> +    ///
> +    /// This function may be used to easily perform early returns
> with the [`?`] operator
> +    /// when working with C APIs within Rust abstractions:
> +    ///
> +    /// ```
> +    /// # use kernel::error::ToResult;
> +    /// # mod bindings {
> +    /// #     #![expect(clippy::missing_safety_doc)]
> +    /// #     use kernel::prelude::*;
> +    /// #     pub(super) unsafe fn f1() -> c_int { 0 }
> +    /// #     pub(super) unsafe fn f2() -> c_int { EINVAL.to_errno()
> }
> +    /// # }
> +    /// fn f() -> Result {
> +    ///     // SAFETY: ...
> +    ///     let _value = unsafe { bindings::f1() }.to_result()?;
> +    ///
> +    ///     // SAFETY: ...
> +    ///     let _value = unsafe { bindings::f2() }.to_result()?;
> +    ///
> +    ///     // ...
> +    ///
> +    ///     Ok(())
> +    /// }
> +    /// # assert_eq!(f(), Err(EINVAL));
> +    /// ```
> +    ///
> +    /// [`?`]:
> https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator
> +    fn to_result(self) -> Result<Self::Unsigned>;
> +}
> +
> +impl ToResult for i32 {
> +    type Unsigned = u32;
> +
> +    fn to_result(self) -> Result<Self::Unsigned> {
> +        if self < 0 {
> +            Err(Error::from_errno(self))
> +        } else {
> +            Ok(self as u32)
> +        }
> +    }
> +}
> +
> +impl ToResult for isize {
> +    type Unsigned = usize;
> +
> +    fn to_result(self) -> Result<Self::Unsigned> {
> +        // Try casting into `i32`.
> +        let casted: crate::ffi::c_int = self.try_into().map_err(|_|
> code::EINVAL)?; +
I should do this casting only when `self < 0`, will fix it later in the
next version.
> +        if casted < 0 {
> +            Err(Error::from_errno(casted))
> +        } else {
> +            Ok(self as usize)
> +        }
> +    }
> +}
> +
>  /// Converts an integer as returned by a C kernel function to a
> [`Result`]. ///
>  /// If the integer is negative, an [`Err`] with an [`Error`] as
> given by [`Error::from_errno`] is
next prev parent reply	other threads:[~2025-10-13 12:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-13 12:41 [PATCH v3 0/2] rust: refactor `to_result` Onur Özkan
2025-10-13 12:41 ` [PATCH v3 1/2] rust: add `ToResult` trait Onur Özkan
2025-10-13 12:48   ` Onur Özkan [this message]
2025-10-13 12:41 ` [PATCH v3 2/2] rust: drop `error::to_result` and utilize `ToResult` Onur Özkan
2025-10-13 17:04   ` Miguel Ojeda
2025-10-13 19:03     ` Onur Özkan
2025-10-13 18:29   ` Alice Ryhl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox
  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):
  git send-email \
    --in-reply-to=20251013154819.15149262@nimda.home \
    --to=work@onurozkan.dev \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=gary@garyguo.net \
    --cc=lossin@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tamird@gmail.com \
    --cc=tmgross@umich.edu \
    /path/to/YOUR_REPLY
  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
  Be sure your reply has a Subject: header at the top and a blank line
  before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).