os_trait/
os_impls.rs

1use crate::{
2    mutex::FakeRawMutex,
3    notifier_impls::*,
4    prelude::*,
5    timeout_trait::{delay::*, fake_impls::*},
6};
7cfg_if::cfg_if! {
8    if #[cfg(feature = "std")] {
9        use std::thread;
10        use crate::timeout_trait::std_impls::*;
11    }
12}
13
14// STD --------------------------------------------------------------
15
16/// This implementation is only for unit testing.
17pub struct StdOs;
18#[cfg(feature = "std")]
19impl OsInterface for StdOs {
20    type RawMutex = FakeRawMutex;
21    type Notifier = StdNotifier;
22    type NotifyWaiter = StdNotifyWaiter;
23    type Instant = StdTickInstant;
24    type Delay = StdDelayNs;
25
26    const O: Self = Self {};
27
28    #[inline]
29    fn yield_thread() {
30        thread::yield_now();
31    }
32
33    #[inline]
34    fn delay() -> Self::Delay {
35        StdDelayNs {}
36    }
37
38    #[inline]
39    fn notify() -> (Self::Notifier, Self::NotifyWaiter) {
40        StdNotifier::new()
41    }
42}
43
44// Fake -------------------------------------------------------------
45
46pub struct FakeOs;
47impl OsInterface for FakeOs {
48    type RawMutex = FakeRawMutex;
49    type Notifier = FakeNotifier;
50    type NotifyWaiter = FakeNotifier;
51    type Instant = FakeTickInstant;
52    type Delay = TickDelay<FakeTickInstant>;
53
54    const O: Self = Self {};
55
56    #[inline]
57    fn yield_thread() {}
58
59    #[inline]
60    fn delay() -> Self::Delay {
61        TickDelay::<FakeTickInstant>::default()
62    }
63
64    #[inline]
65    fn notify() -> (Self::Notifier, Self::NotifyWaiter) {
66        FakeNotifier::new()
67    }
68}
69
70// Tests ------------------------------------------------------------
71
72#[cfg(feature = "std")]
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use crate::{Delay, Duration, Instant, Mutex, Timeout};
77
78    struct OsUser<OS: OsInterface> {
79        notifier: OS::Notifier,
80        waiter: OS::NotifyWaiter,
81        mutex: Mutex<OS, u8>,
82        interval: Timeout<OS>,
83        now: Instant<OS>,
84        delay: Delay<OS>,
85    }
86
87    impl<OS: OsInterface> OsUser<OS> {
88        fn new() -> Self {
89            let (notifier, waiter) = OS::notify();
90            Self {
91                notifier,
92                waiter,
93                mutex: OS::mutex(1),
94                interval: Timeout::<OS>::millis(1),
95                now: Instant::<OS>::now(),
96                delay: OS::delay(),
97            }
98        }
99
100        fn use_os(&mut self) {
101            let mutex = Mutex::<OS, _>::new(0);
102
103            let mut guard = mutex.try_lock().unwrap();
104            assert_eq!(*guard, 0);
105            *guard = 4;
106            drop(guard);
107
108            mutex
109                .try_with_lock(|data| {
110                    assert_eq!(*data, 4);
111                    *data = 5;
112                })
113                .unwrap();
114
115            OS::yield_thread();
116            OS::delay().delay_ms(1);
117
118            assert!(self.notifier.notify());
119            assert!(self.waiter.wait(&Duration::<OS>::millis(1)));
120
121            let mut d = self.mutex.lock();
122            *d = 2;
123
124            self.interval.timeout();
125
126            self.delay.delay_ns(1);
127            self.now.elapsed();
128        }
129    }
130
131    #[test]
132    fn select_os() {
133        let mut user = OsUser::<FakeOs>::new();
134        user.use_os();
135        let mut user = OsUser::<StdOs>::new();
136        user.use_os();
137    }
138}
139
140#[allow(dead_code)]
141#[cfg(feature = "std")]
142#[cfg(test)]
143mod tests_end_type {
144    use crate::{StdOs as OS, os_type_alias, prelude::*};
145
146    os_type_alias!(OS);
147
148    struct EndUser {
149        notifier: Notifier,
150        waiter: NotifyWaiter,
151        mutex: Mutex<u8>,
152        interval: Timeout,
153        dur: Duration,
154        now: Instant,
155        delay: Delay,
156    }
157
158    impl EndUser {
159        pub fn new() -> Self {
160            let (notifier, waiter) = OS::notify();
161            Self {
162                notifier,
163                waiter,
164                mutex: Mutex::new(1),
165                interval: Timeout::millis(1),
166                dur: Duration::millis(1),
167                now: Instant::now(),
168                delay: OS::delay(),
169            }
170        }
171    }
172}