use {
crate::protocol::{Command, Status},
core::convert::Infallible,
};
use crate::traits::UpdateService;
pub struct InMemory<'a> {
expected_version: &'a [u8],
expected_firmware: &'a [u8],
}
impl<'a> InMemory<'a> {
pub fn new(expected_version: &'a [u8], expected_firmware: &'a [u8]) -> Self {
Self {
expected_version,
expected_firmware,
}
}
}
impl<'a> UpdateService for InMemory<'a> {
type Error = Infallible;
async fn request<'m>(&'m mut self, status: &'m Status<'m>) -> Result<Command<'m>, Self::Error> {
if self.expected_version == status.version.as_ref() {
Ok(Command::new_sync(self.expected_version, None, status.correlation_id))
} else if let Some(update) = &status.update {
if update.version == self.expected_version {
if update.offset as usize >= self.expected_firmware.len() {
Ok(Command::new_swap(self.expected_version, &[], status.correlation_id))
} else {
let data = self.expected_firmware;
let mtu = status.mtu.unwrap_or(16) as usize;
let to_copy = core::cmp::min(mtu, data.len() - update.offset as usize);
let s = &data[update.offset as usize..update.offset as usize + to_copy];
Ok(Command::new_write(
self.expected_version,
update.offset,
s,
status.correlation_id,
))
}
} else {
let data = self.expected_firmware;
let mtu = status.mtu.unwrap_or(128) as usize;
let to_copy = core::cmp::min(mtu, data.len());
let s = &data[..to_copy];
Ok(Command::new_write(self.expected_version, 0, s, status.correlation_id))
}
} else {
let data = self.expected_firmware;
let mtu = status.mtu.unwrap_or(128) as usize;
let to_copy = core::cmp::min(mtu, data.len());
let s = &data[..to_copy];
Ok(Command::new_write(self.expected_version, 0, s, status.correlation_id))
}
}
}