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