mavlink_core/connection/file/
async.rs1use core::ops::DerefMut;
3use std::io;
4use std::path::PathBuf;
5
6use crate::connection::file::config::FileConfig;
7use crate::connection::{AsyncConnectable, AsyncMavConnection};
8use crate::connection_shared::{ConnectionState, read_message_async, read_raw_message_async};
9use crate::error::{MessageReadError, MessageWriteError};
10use crate::{
11 MAVLinkMessageRaw, MavHeader, MavlinkVersion, Message, async_peek_reader::AsyncPeekReader,
12};
13
14use async_trait::async_trait;
15use futures::lock::Mutex;
16use tokio::fs::File;
17
18#[cfg(feature = "mav2-message-signing")]
19use crate::SigningConfig;
20
21pub async fn open(file_path: &PathBuf) -> io::Result<AsyncFileConnection> {
22 let file = File::open(file_path).await?;
23 Ok(AsyncFileConnection {
24 file: Mutex::new(AsyncPeekReader::new(file)),
25 state: ConnectionState::new(),
26 })
27}
28
29pub struct AsyncFileConnection {
30 file: Mutex<AsyncPeekReader<File>>,
31 state: ConnectionState,
32}
33
34#[async_trait::async_trait]
35impl<M: Message + Sync + Send> AsyncMavConnection<M> for AsyncFileConnection {
36 async fn recv_raw(&self) -> Result<MAVLinkMessageRaw, crate::error::MessageReadError> {
37 let mut file = self.file.lock().await;
38 loop {
39 let result = read_raw_message_async::<M, _>(file.deref_mut(), &self.state).await;
40 match result {
41 ok @ Ok(..) => {
42 return ok;
43 }
44 Err(MessageReadError::Io(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
45 return Err(MessageReadError::Io(e));
46 }
47 _ => {}
48 }
49 }
50 }
51
52 async fn recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
53 let mut file = self.file.lock().await;
54 loop {
55 let result = read_message_async::<M, _>(file.deref_mut(), &self.state).await;
56 match result {
57 ok @ Ok(..) => {
58 return ok;
59 }
60 Err(MessageReadError::Io(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
61 return Err(MessageReadError::Io(e));
62 }
63 _ => {}
64 }
65 }
66 }
67
68 async fn try_recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
69 let mut file = self.file.lock().await;
70 read_message_async::<M, _>(file.deref_mut(), &self.state).await
71 }
72
73 async fn send(&self, _header: &MavHeader, _data: &M) -> Result<usize, MessageWriteError> {
74 Ok(0)
75 }
76
77 fn set_protocol_version(&mut self, version: MavlinkVersion) {
78 self.state.set_protocol_version(version);
79 }
80
81 fn protocol_version(&self) -> MavlinkVersion {
82 self.state.protocol_version()
83 }
84
85 fn set_allow_recv_any_version(&mut self, allow: bool) {
86 self.state.set_allow_recv_any_version(allow);
87 }
88
89 fn allow_recv_any_version(&self) -> bool {
90 self.state.allow_recv_any_version()
91 }
92
93 #[cfg(feature = "mav2-message-signing")]
94 fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
95 self.state.setup_signing(signing_data);
96 }
97}
98
99#[async_trait]
100impl AsyncConnectable for FileConfig {
101 async fn connect_async<M>(&self) -> io::Result<Box<dyn AsyncMavConnection<M> + Sync + Send>>
102 where
103 M: Message + Sync + Send,
104 {
105 Ok(Box::new(open(&self.address).await?))
106 }
107}