use {
crate::protocol::{Command, Status},
core::fmt::Debug,
};
pub trait UpdateService {
type Error: core::fmt::Debug;
async fn request<'m>(&'m mut self, status: &'m Status<'m>) -> Result<Command<'m>, Self::Error>;
}
#[cfg(feature = "defmt")]
pub trait FirmwareVersion: PartialEq + AsRef<[u8]> + Sized + Debug + Clone + defmt::Format {
fn from_slice(data: &[u8]) -> Result<Self, ()>;
}
#[cfg(not(feature = "defmt"))]
pub trait FirmwareVersion: PartialEq + AsRef<[u8]> + Sized + Debug + Clone {
#[allow(clippy::result_unit_err)]
fn from_slice(data: &[u8]) -> Result<Self, ()>;
}
impl<const N: usize> FirmwareVersion for heapless::Vec<u8, N> {
fn from_slice(data: &[u8]) -> Result<Self, ()> {
heapless::Vec::from_slice(data)
}
}
#[cfg(feature = "std")]
mod stdlib {
extern crate std;
use std::vec::Vec;
impl super::FirmwareVersion for Vec<u8> {
fn from_slice(data: &[u8]) -> Result<Self, ()> {
Ok(data.into())
}
}
}
pub struct FirmwareStatus<VERSION>
where
VERSION: FirmwareVersion,
{
pub current_version: VERSION,
pub next_offset: u32,
pub next_version: Option<VERSION>,
}
impl<VERSION> Clone for FirmwareStatus<VERSION>
where
VERSION: FirmwareVersion + Clone,
{
fn clone(&self) -> Self {
Self {
current_version: self.current_version.clone(),
next_offset: self.next_offset,
next_version: self.next_version.clone(),
}
}
}
pub trait FirmwareDevice {
const MTU: usize;
type Version: FirmwareVersion;
type Error;
async fn status(&mut self) -> Result<FirmwareStatus<Self::Version>, Self::Error>;
async fn start(&mut self, version: &[u8]) -> Result<(), Self::Error>;
async fn write(&mut self, offset: u32, data: &[u8]) -> Result<(), Self::Error>;
async fn update(&mut self, version: &[u8], checksum: &[u8]) -> Result<(), Self::Error>;
async fn synced(&mut self) -> Result<(), Self::Error>;
}