[PATCH v2] rust: types: Add examples for the `Either` type

Nell Shamrell-Harrington posted 1 patch 2 months, 1 week ago
rust/kernel/types.rs | 9 +++++++++
1 file changed, 9 insertions(+)
[PATCH v2] rust: types: Add examples for the `Either` type
Posted by Nell Shamrell-Harrington 2 months, 1 week ago
Add examples for the `Either` type

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Nell Shamrell-Harrington <nells@linux.microsoft.com>
Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
---
V1 -> V2: Cleaned up commit message and addressed review comments

 rust/kernel/types.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index 9e7ca066355c..e2f3ab11cfda 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -461,6 +461,15 @@ fn drop(&mut self) {
 }
 
 /// A sum type that always holds either a value of type `L` or `R`.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::types::Either;
+///
+/// let left_value: Either<i32, &str> = Either::Left(7);
+/// let right_value: Either<i32, &str> = Either::Right("right value");
+/// ```
 pub enum Either<L, R> {
     /// Constructs an instance of [`Either`] containing a value of type `L`.
     Left(L),
-- 
2.34.1
Re: [PATCH v2] rust: types: Add examples for the `Either` type
Posted by Miguel Ojeda 1 month, 4 weeks ago
On Wed, Sep 18, 2024 at 11:21 PM Nell Shamrell-Harrington
<nells@linux.microsoft.com> wrote:
>
> Add examples for the `Either` type
>
> Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> Signed-off-by: Nell Shamrell-Harrington <nells@linux.microsoft.com>
> Tested-by: Dirk Behme <dirk.behme@de.bosch.com>

Applied to `rust-next` -- thanks everyone!

    [ Reworded slightly. - Miguel ]

It could be nice to have `assert_eq!`s too, like in some standard
library examples and/or a "real-life" example like Wedson's (I created
a "good first issue" for that:
https://github.com/Rust-for-Linux/linux/issues/1122), but we can add
that later.

Cheers,
Miguel
[PATCH] rust: types: 'real-life' example for Either
Posted by Timo Grautstueck 1 month, 3 weeks ago
Added a 'real-life' example for the type `Either`. This example
uses a work queue and extends the first example in `workqueue.rs`
(commit ID: 15b286d) to demonstrate how to hold and distinguish
between two different data types.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/1122
Signed-off-by: Timo Grautstueck <timo.grautstueck@web.de>
---
 rust/kernel/types.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index 5ea9126c8c93..a56192141a0c 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -322,6 +322,60 @@ pub const fn raw_get(this: *const Self) -> *mut T {
 /// let left_value: Either<i32, &str> = Either::Left(7);
 /// let right_value: Either<i32, &str> = Either::Right("right value");
 /// ```
+///
+/// The following example demonstrates how we can create a struct
+/// that uses `Either` to hold either an integer or a string.
+/// This struct will be scheduled on the workqueue, and when executed,
+/// we will perform different actions depending on whether it holds
+/// a `Left` value (integer) or a `Right` value (string).
+///
+/// ```
+/// use kernel::prelude::*;
+/// use kernel::sync::Arc;
+/// use kernel::types::Either;
+/// use kernel::workqueue::{self, new_work, Work, WorkItem};
+///
+/// #[pin_data]
+/// struct WorkStruct {
+///     value: Either<i32, &'static str>,
+///     #[pin]
+///     work: Work<WorkStruct>,
+/// }
+///
+/// impl_has_work! {
+///     impl HasWork<Self> for WorkStruct { self.work }
+/// }
+///
+/// impl WorkStruct {
+///     fn new(value: Either<i32, &'static str>) -> Result<Arc<Self>> {
+///         Arc::pin_init(pin_init!(WorkStruct {
+///             value,
+///             work <- new_work!("WorkStruct::work"),
+///         }), GFP_KERNEL)
+///     }
+/// }
+///
+/// impl WorkItem for WorkStruct {
+///     type Pointer = Arc<WorkStruct>;
+///
+///     fn run(this: Arc<WorkStruct>) {
+///         match &this.value {
+///             Either::Left(left_value) => {
+///                 pr_info!("Left value: {}", left_value);
+///                 pr_info!("Left value times two: {}", left_value << 1);
+///             }
+///             Either::Right(right_value) => {
+///                 pr_info!("Right value: {}", right_value);
+///                 pr_info!("Length of right value: {}", right_value.len());
+///             }
+///         }
+///     }
+/// }
+///
+/// fn enqueue_work(work_item: Arc<WorkStruct>) {
+///     let _ = workqueue::system().enqueue(work_item);
+/// }
+/// ```
 pub enum Either<L, R> {
     /// Constructs an instance of [`Either`] containing a value of type `L`.
     Left(L),
--
2.46.2
Re: [PATCH] rust: types: 'real-life' example for Either
Posted by Miguel Ojeda 1 month, 3 weeks ago
On Mon, Oct 7, 2024 at 5:54 PM Timo Grautstueck <timo.grautstueck@web.de> wrote:
>
> Added a 'real-life' example for the type `Either`. This example
> uses a work queue and extends the first example in `workqueue.rs`
> (commit ID: 15b286d) to demonstrate how to hold and distinguish
> between two different data types.
>
> Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> Link: https://github.com/Rust-for-Linux/linux/issues/1122
> Signed-off-by: Timo Grautstueck <timo.grautstueck@web.de>

This is a nice, self-contained example, thanks!

In the linked issue, I was aiming more to have a case where `Either`
was used in an interface (or similar) carrying two existing different
types, i.e. like in the talk I mentioned in the issue. I feel a custom
`enum` may work better anyway for something like the example in this
patch, i.e. when one does not have already types on each side that
make it obvious what each side is about.

So perhaps we can modify this example with two "message" or "action"
types (that may be hidden) or something similar that `Either` can
carry, so that it is a bit more concrete.

It wouldn't hurt either to showcase in addition the interface the talk
showed, perhaps in an `ignore` example so that we don't have to "mock"
everything.

Cheers,
Miguel
Re: [PATCH v2] rust: types: Add examples for the `Either` type
Posted by Alice Ryhl 2 months ago
On Wed, Sep 18, 2024 at 11:21 PM Nell Shamrell-Harrington
<nells@linux.microsoft.com> wrote:
>
> Add examples for the `Either` type
>
> Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> Signed-off-by: Nell Shamrell-Harrington <nells@linux.microsoft.com>
> Tested-by: Dirk Behme <dirk.behme@de.bosch.com>

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Re: [PATCH v2] rust: types: Add examples for the `Either` type
Posted by Trevor Gross 2 months ago
On Wed, Sep 18, 2024 at 5:21 PM Nell Shamrell-Harrington
<nells@linux.microsoft.com> wrote:
>
> Add examples for the `Either` type
>
> Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> Signed-off-by: Nell Shamrell-Harrington <nells@linux.microsoft.com>
> Tested-by: Dirk Behme <dirk.behme@de.bosch.com>

Reviewed-by: Trevor Gross <tmgross@umich.edu>