mutex_trait2/
lib.rs

1#![no_std]
2
3use core::{cell::LazyCell, future::Future, ops::{Deref, DerefMut}};
4// use std::borrow::{Cow, ToOwned};
5
6#[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};