xref: /aosp_15_r20/external/uwb/src/rust/uwb_core/src/utils.rs (revision e0df40009cb5d71e642272d38ba1bb7ffccfce41)
1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use std::future::Future;
16 use std::pin::Pin;
17 use std::task::{Context, Poll};
18 use std::time::Duration;
19 
20 use tokio::sync::mpsc::UnboundedReceiver;
21 use tokio::time::{sleep, Sleep};
22 
23 /// Pinned Sleep instance. It can be used in tokio::select! macro.
24 pub(super) struct PinSleep(Pin<Box<Sleep>>);
25 
26 impl PinSleep {
new(duration: Duration) -> Self27     pub fn new(duration: Duration) -> Self {
28         Self(Box::pin(sleep(duration)))
29     }
30 }
31 
32 impl Future for PinSleep {
33     type Output = ();
34 
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()>35     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
36         self.0.as_mut().poll(cx)
37     }
38 }
39 
40 /// Generate the setter method for the field of the struct for the builder pattern.
41 macro_rules! builder_field {
42     ($field:ident, $ty:ty, $wrap:expr) => {
43         /// Set the $field field.
44         pub fn $field(&mut self, value: $ty) -> &mut Self {
45             self.$field = $wrap(value);
46             self
47         }
48     };
49     ($field:ident, $ty:ty) => {
50         builder_field!($field, $ty, ::std::convert::identity);
51     };
52 }
53 pub(crate) use builder_field;
54 
55 /// Generate the setter method for the field of the struct for the consuming builder pattern.
56 macro_rules! consuming_builder_field {
57     ($field:ident, $ty:ty, $wrap:expr) => {
58         /// Set the $field field.
59         pub fn $field(mut self, value: $ty) -> Self {
60             self.$field = $wrap(value);
61             self
62         }
63     };
64     ($field:ident, $ty:ty) => {
65         consuming_builder_field!($field, $ty, ::std::convert::identity);
66     };
67 }
68 pub(crate) use consuming_builder_field;
69 
70 /// Generate the getter method for the field of the struct.
71 macro_rules! getter_field {
72     ($field:ident, $ty:ty) => {
73         pub fn $field(&self) -> &$ty {
74             &self.$field
75         }
76     };
77 }
78 pub(crate) use getter_field;
79 
80 /// Clean shutdown a mpsc receiver.
81 ///
82 /// Call this function before dropping the receiver if the sender is not dropped yet.
clean_mpsc_receiver<T>(receiver: &mut UnboundedReceiver<T>)83 pub fn clean_mpsc_receiver<T>(receiver: &mut UnboundedReceiver<T>) {
84     receiver.close();
85     while receiver.try_recv().is_ok() {}
86 }
87 
88 #[cfg(test)]
init_test_logging()89 pub fn init_test_logging() {
90     let _ = env_logger::builder().is_test(true).try_init();
91 }
92 
93 #[cfg(test)]
94 mod tests {
95     struct Foo {
96         value: u32,
97     }
98 
99     impl Foo {
new(value: u32) -> Self100         pub fn new(value: u32) -> Self {
101             Self { value }
102         }
103 
104         getter_field!(value, u32);
105     }
106 
107     #[test]
test_getter_field()108     fn test_getter_field() {
109         let foo = Foo::new(5);
110         assert_eq!(foo.value(), &5);
111     }
112 }
113