1#![no_std]
2
3use core::{cell::LazyCell, future::Future, ops::{Deref, DerefMut}};
4#[cfg(feature = "alloc")]
7extern crate alloc;
8
9#[cfg(feature = "std")]
10extern crate std;
11
12pub trait Mutex {
13 type Data;
14 fn lock(&self) -> impl DerefMut<Target = Self::Data>;
15}
16
17#[cfg(feature = "std")]
18impl<T> Mutex for std::sync::Mutex<T> {
19 type Data = T;
20
21 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
22 std::sync::Mutex::lock(self).expect("poison")
23 }
24}
25
26pub trait AsyncMutex{
27 type Data;
28 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>>;
29}
30impl<'a,T: Mutex> Mutex for &'a T{
31 type Data = T::Data;
32
33 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
34 (**self).lock()
35 }
36}
37impl<'a,T: AsyncMutex> AsyncMutex for &'a T{
38 type Data = T::Data;
39
40 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
41 (**self).lock()
42 }
43}
44
45impl<T: Mutex,F: FnOnce() -> T> Mutex for LazyCell<T,F>{
46 type Data = T::Data;
47
48 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
49 (**self).lock()
50 }
51}
52impl<T: AsyncMutex,F: FnOnce() -> T> AsyncMutex for LazyCell<T,F>{
53 type Data = T::Data;
54
55 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
56 (**self).lock()
57 }
58}
59#[macro_export]
60macro_rules! type_param_deref_mutex {
61 ($a:ident) => {
62 impl<T: $crate::Mutex> $crate::Mutex for $a<T>{
63 type Data = T::Data;
64
65 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
66 (**self).lock()
67 }
68 }
69 impl<T: $crate::AsyncMutex> $crate::AsyncMutex for $a<T>{
70 type Data = T::Data;
71
72 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
73 (**self).lock()
74 }
75 }
76 };
77}
78#[cfg(feature = "alloc")]
79const _: () = {
80 use alloc::rc::Rc;
81
82 use alloc::sync::Arc;
83 use alloc::borrow::*;
84
85 type_param_deref_mutex!(Arc);
86 type_param_deref_mutex!(Rc);
87 impl<'a,T: Mutex + ToOwned> Mutex for Cow<'a,T>{
88 type Data = T::Data;
89
90 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
91 (**self).lock()
92 }
93 }
94 impl<'a,T: AsyncMutex + ToOwned> AsyncMutex for Cow<'a,T>{
95 type Data = T::Data;
96
97 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
98 (**self).lock()
99 }
100 }
101};
102#[cfg(feature = "std")]
103const _: () = {
104 use std::sync::LazyLock;
105
106 impl<T: Mutex,F: FnOnce() -> T> Mutex for LazyLock<T,F>{
107 type Data = T::Data;
108
109 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
110 (**self).lock()
111 }
112 }
113 impl<T: AsyncMutex,F: FnOnce() -> T> AsyncMutex for LazyLock<T,F>{
114 type Data = T::Data;
115
116 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
117 (**self).lock()
118 }
119 }
120};
121#[cfg(feature = "futures")]
122impl<T> AsyncMutex for futures::lock::Mutex<T>{
123 type Data = T;
124
125 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
126 self.lock()
127 }
128}
129#[cfg(feature = "embassy-sync")]
130const _: () = {
131 use embassy_sync::blocking_mutex::raw::RawMutex;
132
133 impl<M: RawMutex,T> AsyncMutex for embassy_sync::mutex::Mutex<M,T>{
134 type Data = T;
135
136 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
137 self.lock()
138 }
139 }
140};
141#[cfg(feature = "no-std-async")]
142const _: () = {
143 impl <T> AsyncMutex for no_std_async::Mutex<T>{
144 type Data = T;
145
146 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
147 self.lock()
148 }
149 }
150};
151#[derive(Clone)]
152pub struct PreShared<T: Clone>{
153 pub contents: T,
154}
155impl<T: Clone> Deref for PreShared<T>{
156 type Target = T;
157
158 fn deref(&self) -> &Self::Target {
159 &self.contents
160 }
161}
162impl<T: Clone> DerefMut for PreShared<T>{
163 fn deref_mut(&mut self) -> &mut Self::Target {
164 &mut self.contents
165 }
166}
167impl<T: Clone> Mutex for PreShared<T>{
168 type Data = T;
169
170 fn lock(&self) -> impl DerefMut<Target = Self::Data> {
171 self.clone()
172 }
173}
174impl<T: Clone> AsyncMutex for PreShared<T>{
175 type Data = T;
176
177 fn lock(&self) -> impl Future<Output: DerefMut<Target = Self::Data>> {
178 core::future::ready(self.clone())
179 }
180}
181#[derive(Clone)]
182pub struct M<T>(pub T);
183#[derive(Clone)]
184pub struct AM<T>(pub T);
185#[cfg(feature = "embedded-io")]
186const _: () = {
187 impl<T: Mutex<Data: embedded_io::ErrorType>> embedded_io::ErrorType for M<T>{
188 type Error = <T::Data as embedded_io::ErrorType>::Error;
189 }
190 impl<T: Mutex<Data: embedded_io::Read>> embedded_io::Read for M<T>{
191 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
192 self.0.lock().read(buf)
193 }
194 }
195 impl<T: Mutex<Data: embedded_io::Write>> embedded_io::Write for M<T>{
196 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
197 self.0.lock().write(buf)
198 }
199
200 fn flush(&mut self) -> Result<(), Self::Error> {
201 self.0.lock().flush()
202 }
203 }
204};
205#[cfg(feature = "embedded-io-async")]
206const _: () = {
207 impl<T: AsyncMutex<Data: embedded_io_async::ErrorType>> embedded_io_async::ErrorType for AM<T>{
208 type Error = <T::Data as embedded_io_async::ErrorType>::Error;
209 }
210 impl<T: AsyncMutex<Data: embedded_io_async::Read>> embedded_io_async::Read for AM<T>{
211 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
212 self.0.lock().await.read(buf).await
213 }
214 }
215 impl<T: AsyncMutex<Data: embedded_io_async::Write>> embedded_io_async::Write for AM<T>{
216 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
217 self.0.lock().await.write(buf).await
218 }
219
220 async fn flush(&mut self) -> Result<(), Self::Error> {
221 self.0.lock().await.flush().await
222 }
223 }
224};