use core::marker::PhantomData;
use crate::error::Result;
use crate::protocol::{
Behold, ComponentId, Frame, MavLinkId, MaybeVersioned, Message, Sequence, Sequencer, SystemId,
Versioned, Versionless, V1, V2,
};
#[derive(Debug)]
pub struct Endpoint<V: MaybeVersioned> {
id: MavLinkId,
sequencer: Sequencer,
_version: PhantomData<V>,
}
impl Endpoint<Versionless> {
pub fn new<V: MaybeVersioned>(id: MavLinkId) -> Endpoint<V> {
Endpoint {
id,
sequencer: Sequencer::new(),
_version: PhantomData,
}
}
#[inline]
pub fn v1(id: MavLinkId) -> Endpoint<V1> {
Endpoint::new(id)
}
#[inline]
pub fn v2(id: MavLinkId) -> Endpoint<V2> {
Endpoint::new(id)
}
#[inline]
pub fn versionless(id: MavLinkId) -> Endpoint<Versionless> {
Endpoint::new(id)
}
pub fn next_frame<V: Versioned>(&self, message: &dyn Message) -> Result<Frame<Versionless>> {
Ok(self._next_frame::<V>(message)?.into_versionless())
}
}
impl<V: MaybeVersioned> Endpoint<V> {
#[inline(always)]
pub fn id(&self) -> MavLinkId {
self.id
}
#[inline(always)]
pub fn system_id(&self) -> SystemId {
self.id.system
}
#[inline(always)]
pub fn component_id(&self) -> ComponentId {
self.id.component
}
#[inline(always)]
pub fn next_sequence(&self) -> Sequence {
self.sequencer.next()
}
#[inline(always)]
pub fn sequencer(&self) -> &Sequencer {
&self.sequencer
}
pub fn advance(&self, increment: Sequence) -> Behold<Sequence> {
self.sequencer.advance(increment)
}
pub fn fork(&self) -> Self {
Self {
id: self.id,
sequencer: self.sequencer.fork(),
_version: PhantomData,
}
}
pub fn sync<Version: MaybeVersioned>(&self, other: &Endpoint<Version>) {
self.sequencer.sync(other.sequencer())
}
#[cfg(feature = "alloc")]
pub fn join<Version: MaybeVersioned>(&self, other: &mut Endpoint<Version>) {
self.sequencer.join(&mut other.sequencer)
}
fn _next_frame<Version: Versioned>(&self, message: &dyn Message) -> Result<Frame<Version>> {
let frame = Frame::builder()
.sequence(self.next_sequence())
.system_id(self.system_id())
.component_id(self.component_id())
.version(Version::v())
.message(message)?
.build();
Ok(frame)
}
}
impl<V: Versioned> Endpoint<V> {
pub fn next_frame(&self, message: &dyn Message) -> Result<Frame<V>> {
self._next_frame::<V>(message)
}
}
#[cfg(feature = "alloc")]
impl<V: MaybeVersioned> Clone for Endpoint<V> {
fn clone(&self) -> Self {
Self {
id: self.id,
sequencer: self.sequencer.clone(),
_version: PhantomData,
}
}
}