wlan_ffi_transport/
completers.rs
1pub struct Completer<F>
10where
11 F: FnOnce(zx::sys::zx_status_t),
12{
13 completer: Option<F>,
14}
15
16unsafe impl<F> Send for Completer<F> where F: FnOnce(zx::sys::zx_status_t) {}
19
20impl<F> Completer<F>
21where
22 F: FnOnce(zx::sys::zx_status_t),
23{
24 pub unsafe fn new_unchecked(completer: F) -> Self {
30 Self { completer: Some(completer) }
31 }
32
33 pub fn reply(mut self, status: Result<(), zx::Status>) {
34 let completer = match self.completer.take() {
35 None => unreachable!(),
36 Some(completer) => completer,
37 };
38 completer(zx::Status::from(status).into_raw())
39 }
40}
41
42impl<F> Completer<F>
43where
44 F: FnOnce(zx::sys::zx_status_t) + Send,
45{
46 pub fn new(completer: F) -> Self {
47 Self { completer: Some(completer) }
48 }
49}
50
51impl<F> Drop for Completer<F>
52where
53 F: FnOnce(zx::sys::zx_status_t),
54{
55 fn drop(&mut self) {
56 if let Some(completer) = self.completer.take() {
57 completer(zx::Status::BAD_STATE.into_raw())
58 }
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use futures::channel::oneshot;
66
67 #[test]
68 fn reply_with_ok() {
69 let (sender, mut receiver) = oneshot::channel::<zx::sys::zx_status_t>();
70 let completer = Completer::new(move |status| {
71 sender.send(status).expect("Failed to send result.");
72 });
73 completer.reply(Ok(()));
74 assert_eq!(Ok(Some(zx::Status::OK.into_raw())), receiver.try_recv());
75 }
76
77 #[test]
78 fn reply_with_error() {
79 let (sender, mut receiver) = oneshot::channel::<zx::sys::zx_status_t>();
80 let completer = Completer::new(move |status| {
81 sender.send(status).expect("Failed to send result.");
82 });
83 completer.reply(Err(zx::Status::NO_RESOURCES));
84 assert_eq!(Ok(Some(zx::Status::NO_RESOURCES.into_raw())), receiver.try_recv());
85 }
86
87 #[test]
88 fn reply_with_error_when_dropped() {
89 let (sender, mut receiver) = oneshot::channel::<zx::sys::zx_status_t>();
90 let completer = Completer::new(move |status| {
91 sender.send(status).expect("Failed to send result.");
92 });
93 drop(completer);
94 assert_eq!(Ok(Some(zx::Status::BAD_STATE.into_raw())), receiver.try_recv());
95 }
96}