Re: [PATCH] rust: clk: use the type-state pattern

From: Daniel Sedlak
Date: Wed Jul 30 2025 - 03:29:45 EST


Hi Daniel,

On 7/29/25 11:38 PM, Daniel Almeida wrote:
+ mod private {
+ pub trait Sealed {}
+
+ impl Sealed for super::Unprepared {}
+ impl Sealed for super::Prepared {}
+ impl Sealed for super::Enabled {}
+ }

I just noticed we have plenty of Sealed traits scattered across rust/ folder. Do you think we would benefit from unifying it to a single location to prevent duplication?

+
+ /// A trait representing the different states that a [`Clk`] can be in.
+ pub trait ClkState: private::Sealed {
+ /// Whether the clock should be disabled when dropped.
+ const DISABLE_ON_DROP: bool;
+
+ /// Whether the clock should be unprepared when dropped.
+ const UNPREPARE_ON_DROP: bool;
+ }
+
+ /// A state where the [`Clk`] is not prepared and not enabled.
+ pub struct Unprepared;
+
+ /// A state where the [`Clk`] is prepared but not enabled.
+ pub struct Prepared;
+
+ /// A state where the [`Clk`] is both prepared and enabled.
+ pub struct Enabled;

I would put a private member into the structs so the user of this API cannot construct it themself without using your abstractions.

pub struct Unprepared(());
pub struct Prepared(());
pub struct Enabled(());

+
+ impl ClkState for Unprepared {
+ const DISABLE_ON_DROP: bool = false;
+ const UNPREPARE_ON_DROP: bool = false;
+ }
+
+ impl ClkState for Prepared {
+ const DISABLE_ON_DROP: bool = false;
+ const UNPREPARE_ON_DROP: bool = true;
+ }
+
+ impl ClkState for Enabled {
+ const DISABLE_ON_DROP: bool = true;
+ const UNPREPARE_ON_DROP: bool = true;
+ }
+
+ /// An error that can occur when trying to convert a [`Clk`] between states.
+ pub struct Error<State: ClkState> {

Nit: IMO we mostly use the `where` variant instead of the colon.

pub struct Error<State>
where State: ClkState

But does it make sense to put the bounds on the structs? Shouldn't be enough but but the bounds on the impl block?

+ /// The error that occurred.
+ pub error: kernel::error::Error,
+
+ /// The [`Clk`] that caused the error, so that the operation may be
+ /// retried.
+ pub clk: Clk<State>,
+ }

Thanks!
Daniel