use crate::core::SubjectId;
use emcyphal_encoding as enc;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Heartbeat {
pub uptime: u32,
pub health: Health,
pub mode: Mode,
pub vendor_specific_status_code: u8,
}
impl enc::DataType for Heartbeat {
const EXTENT_BYTES: Option<u32> = Some(12);
}
impl enc::Message for Heartbeat {}
impl enc::BufferType for Heartbeat {
type Buffer = enc::StaticBuffer<7>;
}
impl Heartbeat {
pub const SUBJECT: SubjectId = SubjectId::new(7509).unwrap();
pub const MAX_PUBLICATION_PERIOD: u16 = 1;
#[allow(dead_code)]
pub const OFFLINE_TIMEOUT: u16 = 3;
}
impl enc::Serialize for Heartbeat {
fn size_bits(&self) -> usize {
56
}
fn serialize(&self, cursor: &mut enc::WriteCursor<'_>) {
cursor.write_aligned_u32(self.uptime);
cursor.write_composite(&self.health);
cursor.write_composite(&self.mode);
cursor.write_aligned_u8(self.vendor_specific_status_code);
}
}
impl enc::Deserialize for Heartbeat {
fn deserialize(
cursor: &mut enc::ReadCursor<'_>,
) -> ::core::result::Result<Self, enc::DeserializeError>
where
Self: Sized,
{
Ok(Heartbeat {
uptime: { cursor.read_u32() as _ },
health: { cursor.read_composite()? },
mode: { cursor.read_composite()? },
vendor_specific_status_code: { cursor.read_u8() as _ },
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Health {
Nominal,
Advisory,
Caution,
Warning,
}
impl enc::DataType for Health {
const EXTENT_BYTES: Option<u32> = None;
}
impl enc::Message for Health {}
impl Health {}
impl enc::Serialize for Health {
fn size_bits(&self) -> usize {
8
}
fn serialize(&self, cursor: &mut enc::WriteCursor<'_>) {
match self {
Health::Nominal => {
cursor.write_u2(0);
}
Health::Advisory => {
cursor.write_u2(1);
}
Health::Caution => {
cursor.write_u2(2);
}
Health::Warning => {
cursor.write_u2(3);
}
}
}
}
impl enc::Deserialize for Health {
fn deserialize(
cursor: &mut enc::ReadCursor<'_>,
) -> ::core::result::Result<Self, enc::DeserializeError>
where
Self: Sized,
{
match cursor.read_u2() as _ {
0 => Ok(Health::Nominal),
1 => Ok(Health::Advisory),
2 => Ok(Health::Caution),
3 => Ok(Health::Warning),
_ => Err(enc::DeserializeError::UnionTag),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Mode {
Operational,
Initialization,
Maintenance,
SoftwareUpdate,
}
impl enc::DataType for Mode {
const EXTENT_BYTES: Option<u32> = None;
}
impl enc::Message for Mode {}
impl enc::BufferType for Mode {
type Buffer = enc::StaticBuffer<1>;
}
impl Mode {}
impl enc::Serialize for Mode {
fn size_bits(&self) -> usize {
8
}
fn serialize(&self, cursor: &mut enc::WriteCursor<'_>) {
match self {
Mode::Operational => {
cursor.write_u3(0);
}
Mode::Initialization => {
cursor.write_u3(1);
}
Mode::Maintenance => {
cursor.write_u3(2);
}
Mode::SoftwareUpdate => {
cursor.write_u3(3);
}
}
}
}
impl enc::Deserialize for Mode {
fn deserialize(
cursor: &mut enc::ReadCursor<'_>,
) -> ::core::result::Result<Self, enc::DeserializeError>
where
Self: Sized,
{
match cursor.read_u3() as _ {
0 => Ok(Mode::Operational),
1 => Ok(Mode::Initialization),
2 => Ok(Mode::Maintenance),
3 => Ok(Mode::SoftwareUpdate),
_ => Err(enc::DeserializeError::UnionTag),
}
}
}