aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy/src/util/mod.rs73
-rw-r--r--embassy/src/util/select.rs (renamed from embassy/src/util/select_all.rs)0
-rw-r--r--embassy/src/util/steal.rs3
-rw-r--r--embassy/src/util/unborrow.rs60
4 files changed, 69 insertions, 67 deletions
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs
index f5cc96238..928edf0e2 100644
--- a/embassy/src/util/mod.rs
+++ b/embassy/src/util/mod.rs
@@ -1,74 +1,13 @@
1//! Misc utilities 1//! Misc utilities
2 2
3mod forever; 3mod forever;
4mod select_all; 4mod select;
5mod steal;
6mod unborrow;
5mod yield_now; 7mod yield_now;
6 8
7pub use forever::*; 9pub use forever::*;
8pub use select_all::*; 10pub use select::*;
11pub use steal::*;
12pub use unborrow::*;
9pub use yield_now::*; 13pub use yield_now::*;
10
11/// Unsafely unborrow an owned singleton out of a `&mut`.
12///
13/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
14/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T.
15///
16/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
17/// to store pointers in the borrowed case.
18///
19/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause
20/// immediate UB when copied, and must not cause UB when copies are later used, provided they
21/// are only used according the [`Self::unborrow`] safety contract.
22///
23pub unsafe trait Unborrow {
24 /// Unborrow result type
25 type Target;
26
27 /// Unborrow a value.
28 ///
29 /// Safety: This returns a copy of a singleton that's normally not
30 /// copiable. The returned copy must ONLY be used while the lifetime of `self` is
31 /// valid, as if it were accessed through `self` every time.
32 unsafe fn unborrow(self) -> Self::Target;
33}
34
35unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T {
36 type Target = T::Target;
37 unsafe fn unborrow(self) -> Self::Target {
38 T::unborrow(core::ptr::read(self))
39 }
40}
41
42pub trait Steal {
43 unsafe fn steal() -> Self;
44}
45
46macro_rules! unsafe_impl_unborrow_tuples {
47 ($($t:ident),+) => {
48 unsafe impl<$($t),+> Unborrow for ($($t),+)
49 where
50 $(
51 $t: Unborrow<Target = $t>
52 ),+
53 {
54 type Target = ($($t),+);
55 unsafe fn unborrow(self) -> Self::Target {
56 self
57 }
58 }
59
60
61 };
62}
63
64unsafe_impl_unborrow_tuples!(A, B);
65unsafe_impl_unborrow_tuples!(A, B, C);
66unsafe_impl_unborrow_tuples!(A, B, C, D);
67unsafe_impl_unborrow_tuples!(A, B, C, D, E);
68unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
69unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
70unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
71unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
72unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
73unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
74unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
diff --git a/embassy/src/util/select_all.rs b/embassy/src/util/select.rs
index aef22d894..aef22d894 100644
--- a/embassy/src/util/select_all.rs
+++ b/embassy/src/util/select.rs
diff --git a/embassy/src/util/steal.rs b/embassy/src/util/steal.rs
new file mode 100644
index 000000000..a0d5f1359
--- /dev/null
+++ b/embassy/src/util/steal.rs
@@ -0,0 +1,3 @@
1pub trait Steal {
2 unsafe fn steal() -> Self;
3}
diff --git a/embassy/src/util/unborrow.rs b/embassy/src/util/unborrow.rs
new file mode 100644
index 000000000..dacfa3d42
--- /dev/null
+++ b/embassy/src/util/unborrow.rs
@@ -0,0 +1,60 @@
1/// Unsafely unborrow an owned singleton out of a `&mut`.
2///
3/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
4/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T.
5///
6/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
7/// to store pointers in the borrowed case.
8///
9/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause
10/// immediate UB when copied, and must not cause UB when copies are later used, provided they
11/// are only used according the [`Self::unborrow`] safety contract.
12///
13pub unsafe trait Unborrow {
14 /// Unborrow result type
15 type Target;
16
17 /// Unborrow a value.
18 ///
19 /// Safety: This returns a copy of a singleton that's normally not
20 /// copiable. The returned copy must ONLY be used while the lifetime of `self` is
21 /// valid, as if it were accessed through `self` every time.
22 unsafe fn unborrow(self) -> Self::Target;
23}
24
25unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T {
26 type Target = T::Target;
27 unsafe fn unborrow(self) -> Self::Target {
28 T::unborrow(core::ptr::read(self))
29 }
30}
31
32macro_rules! unsafe_impl_unborrow_tuples {
33 ($($t:ident),+) => {
34 unsafe impl<$($t),+> Unborrow for ($($t),+)
35 where
36 $(
37 $t: Unborrow<Target = $t>
38 ),+
39 {
40 type Target = ($($t),+);
41 unsafe fn unborrow(self) -> Self::Target {
42 self
43 }
44 }
45
46
47 };
48}
49
50unsafe_impl_unborrow_tuples!(A, B);
51unsafe_impl_unborrow_tuples!(A, B, C);
52unsafe_impl_unborrow_tuples!(A, B, C, D);
53unsafe_impl_unborrow_tuples!(A, B, C, D, E);
54unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
55unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
56unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
57unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
58unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
59unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
60unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);