autd3_core/link/
async.rs

1use crate::{
2    geometry::Geometry,
3    link::{LinkError, RxMessage, TxMessage},
4};
5
6pub use internal::AsyncLink;
7
8#[cfg(feature = "async-trait")]
9mod internal {
10    use super::*;
11
12    /// A trait that provides the interface with the device.
13    #[async_trait::async_trait]
14    pub trait AsyncLink: Send {
15        /// Opens the link.
16        async fn open(&mut self, geometry: &Geometry) -> Result<(), LinkError>;
17
18        /// Closes the link.
19        async fn close(&mut self) -> Result<(), LinkError>;
20
21        #[doc(hidden)]
22        async fn update(&mut self, _: &Geometry) -> Result<(), LinkError> {
23            Ok(())
24        }
25
26        /// Allocate a sending buffer for the link.
27        async fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError>;
28
29        /// Sends a message to the device.
30        async fn send(&mut self, tx: Vec<TxMessage>) -> Result<(), LinkError>;
31
32        /// Receives a message from the device.
33        async fn receive(&mut self, rx: &mut [RxMessage]) -> Result<(), LinkError>;
34
35        /// Checks if the link is open.
36        #[must_use]
37        fn is_open(&self) -> bool;
38
39        /// Ensures that the link is open, returning an error if it is not.
40        fn ensure_is_open(&self) -> Result<(), LinkError> {
41            if self.is_open() {
42                Ok(())
43            } else {
44                Err(LinkError::closed())
45            }
46        }
47    }
48
49    #[async_trait::async_trait]
50    impl AsyncLink for Box<dyn AsyncLink> {
51        async fn open(&mut self, geometry: &Geometry) -> Result<(), LinkError> {
52            self.as_mut().open(geometry).await
53        }
54
55        async fn close(&mut self) -> Result<(), LinkError> {
56            self.as_mut().close().await
57        }
58
59        async fn update(&mut self, geometry: &Geometry) -> Result<(), LinkError> {
60            self.as_mut().update(geometry).await
61        }
62
63        async fn alloc_tx_buffer(&mut self) -> Result<Vec<TxMessage>, LinkError> {
64            self.as_mut().alloc_tx_buffer().await
65        }
66
67        async fn send(&mut self, tx: Vec<TxMessage>) -> Result<(), LinkError> {
68            self.as_mut().send(tx).await
69        }
70
71        async fn receive(&mut self, rx: &mut [RxMessage]) -> Result<(), LinkError> {
72            self.as_mut().receive(rx).await
73        }
74
75        fn is_open(&self) -> bool {
76            self.as_ref().is_open()
77        }
78    }
79}
80
81#[cfg(not(feature = "async-trait"))]
82mod internal {
83    use super::*;
84
85    /// A trait that provides the interface with the device.
86    pub trait AsyncLink: Send {
87        /// Opens the link.
88        fn open(
89            &mut self,
90            geometry: &Geometry,
91        ) -> impl std::future::Future<Output = Result<(), LinkError>>;
92
93        /// Closes the link.
94        fn close(&mut self) -> impl std::future::Future<Output = Result<(), LinkError>>;
95
96        #[doc(hidden)]
97        fn update(
98            &mut self,
99            _: &Geometry,
100        ) -> impl std::future::Future<Output = Result<(), LinkError>> {
101            async { Ok(()) }
102        }
103
104        /// Allocate a sending buffer for the link.
105        fn alloc_tx_buffer(
106            &mut self,
107        ) -> impl std::future::Future<Output = Result<Vec<TxMessage>, LinkError>>;
108
109        /// Sends a message to the device.
110        fn send(
111            &mut self,
112            tx: Vec<TxMessage>,
113        ) -> impl std::future::Future<Output = Result<(), LinkError>>;
114
115        /// Receives a message from the device.
116        fn receive(
117            &mut self,
118            rx: &mut [RxMessage],
119        ) -> impl std::future::Future<Output = Result<(), LinkError>>;
120
121        /// Checks if the link is open.
122        #[must_use]
123        fn is_open(&self) -> bool;
124
125        /// Ensures that the link is open, returning an error if it is not.
126        fn ensure_is_open(&self) -> Result<(), LinkError> {
127            if self.is_open() {
128                Ok(())
129            } else {
130                Err(LinkError::closed())
131            }
132        }
133    }
134}