1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
//! # MAVLink frame writer
use core::marker::PhantomData;
use crate::io::Write;
use crate::protocol::{Frame, MaybeVersioned, Versioned, Versionless};
use crate::prelude::*;
/// Sends MAVLink frames.
///
/// Sends MAVLink frames to an instance of [`Write`].
#[derive(Clone, Debug)]
pub struct Sender<W: Write, V: MaybeVersioned> {
writer: W,
_marker_version: PhantomData<V>,
}
impl<W: Write> Sender<W, Versionless> {
/// Default constructor.
pub fn new<V: MaybeVersioned>(writer: W) -> Sender<W, V> {
Sender {
writer,
_marker_version: PhantomData,
}
}
/// Create a MAVLink version agnostic sender.
///
/// Creates a protocol-agnostic sender which can send both `MAVLink 1` and `MAVLink 2` frames.
///
/// If you want a sender that sends only frames restricted to a particular MAVLink protocol
/// version, use [`Sender::versioned`].
///
/// If you want to instantiate a generic sender, use [`Sender::new`].
pub fn versionless(writer: W) -> Self {
Sender::new(writer)
}
/// Create a receiver specific to a particular MAVLink protocol version.
///
/// Same as [`Sender::new::<V1>`] / [`Sender::new::<V2>`] but with an explicit `version`
/// marker as parameter.
///
/// If you want to send both `MAVLink 1` and `MAVLink 2` frames, use [`Sender::versionless`].
pub fn versioned<Version: Versioned>(
writer: W,
#[allow(unused_variables)] version: Version,
) -> Sender<W, Version> {
Sender::new(writer)
}
}
impl<W: Write, V: MaybeVersioned> Sender<W, V> {
/// Sends MAVLink [`Frame`].
///
/// Blocks until all bytes written and returns the number of bytes sent.
///
/// [`Versioned`] sender accepts only frames of a specific MAVLink protocol version.
///
/// [`Versionless`] sender accepts both `MAVLink 1` and `MAVLink 2` frames as
/// [`Frame<Versionless>`].
pub fn send(&mut self, frame: &Frame<V>) -> Result<usize> {
V::expect(frame.version())?;
frame.send(&mut self.writer)
}
/// Flushes all buffers.
///
/// Certain writers require flush to be called on tear down in order to write all contents.
pub fn flush(&mut self) -> Result<()> {
self.writer.flush().map_err(Error::from)
}
}