rp2040_hal/
typelevel.rs

1//! Module supporting type-level programming
2//!
3//! This is heavily inspired by the work in [`atsamd-rs`](https://github.com/atsamd-rs/atsamd). Please refer to the
4//! [documentation](https://docs.rs/atsamd-hal/0.15.1/atsamd_hal/typelevel/index.html)
5//! over there for more details.
6
7mod private {
8    /// Super trait used to mark traits with an exhaustive set of
9    /// implementations
10    pub trait Sealed {}
11}
12
13use core::borrow::{Borrow, BorrowMut};
14
15pub(crate) use private::Sealed;
16
17impl<A: Sealed, B: Sealed> Sealed for (A, B) {}
18impl<A: Sealed, B: Sealed, C: Sealed> Sealed for (A, B, C) {}
19impl<A: Sealed, B: Sealed, C: Sealed, D: Sealed> Sealed for (A, B, C, D) {}
20
21impl Sealed for frunk::HNil {}
22impl<H: Sealed, T: Sealed> Sealed for frunk::HCons<H, T> {}
23
24/// Marker trait for type identity
25///
26/// This trait is used as part of the [`AnyKind`] trait pattern. It represents
27/// the concept of type identity, because all implementors have
28/// `<Self as Is>::Type == Self`. When used as a trait bound with a specific
29/// type, it guarantees that the corresponding type parameter is exactly the
30/// specific type. Stated differently, it guarantees that `T == Specific` in
31/// the following example.
32///
33/// ```text
34/// where T: Is<Type = Specific>
35/// ```
36///
37/// Moreover, the super traits guarantee that any instance of or reference to a
38/// type `T` can be converted into the `Specific` type.
39///
40/// ```
41/// # use rp2040_hal::typelevel::Is;
42/// # struct Specific;
43/// fn example<T>(mut any: T)
44/// where
45///     T: Is<Type = Specific>,
46/// {
47///     let specific_mut: &mut Specific = any.borrow_mut();
48///     let specific_ref: &Specific = any.borrow();
49///     let specific: Specific = any.into();
50/// }
51/// ```
52///
53/// [`AnyKind`]: https://docs.rs/atsamd-hal/0.15.1/atsamd_hal/typelevel/index.html#anykind-trait-pattern
54pub trait Is
55where
56    Self: Sealed,
57    Self: From<IsType<Self>>,
58    Self: Into<IsType<Self>>,
59    Self: Borrow<IsType<Self>>,
60    Self: BorrowMut<IsType<Self>>,
61{
62    #[allow(missing_docs)]
63    type Type;
64}
65
66/// Type alias for [`Is::Type`]
67pub type IsType<T> = <T as Is>::Type;
68
69impl<T> Is for T
70where
71    T: Sealed + Borrow<T> + BorrowMut<T>,
72{
73    type Type = T;
74}
75
76// =====================
77// Type level option
78// =====================
79
80/// Type-level `enum` for Option.
81pub trait OptionT: Sealed {
82    /// Is this Some or None ?
83    const IS_SOME: bool;
84}
85
86/// Type-level variant for `OptionT`
87pub struct OptionTNone;
88impl Sealed for OptionTNone {}
89impl OptionT for OptionTNone {
90    const IS_SOME: bool = false;
91}
92
93/// Type-level variant for `OptionT`
94pub struct OptionTSome<T>(pub T);
95impl<T> Sealed for OptionTSome<T> {}
96impl<T> OptionT for OptionTSome<T> {
97    const IS_SOME: bool = true;
98}