#![no_std]
use core::num::NonZeroU8;
use ufmt::derive::uDebug;
use zerocopy::{AsBytes, FromBytes, FromZeroes};
pub use ie_base::IEBuf;
pub const BINDINGS_BYTES_CAP: usize = 512;
#[repr(C, align(8))]
#[derive(AsBytes, FromZeroes, FromBytes, Debug)]
pub struct Config(pub [u8; 504]);
#[repr(C, align(8))]
#[derive(AsBytes, FromZeroes, FromBytes, Debug)]
pub struct Shared {
pub latched_params: [u8; BINDINGS_BYTES_CAP],
pub latched_ports: [u8; BINDINGS_BYTES_CAP],
}
#[repr(C, align(8))]
#[derive(AsBytes, FromZeroes, FromBytes, Debug)]
pub struct FactoryInput {
pub control_period_ms: u32,
pub config_len: u32,
pub config: Config
}
pub const REQUIRED: u8 = 0x0001;
#[repr(u8)]
#[derive(Debug, Clone, Copy, uDebug)]
pub enum ParseError {
NotTerminated,
NotEnoughData,
TooMuchData,
InvalidData,
BadHeader,
MultiplePointsForSingular,
}
#[repr(C)]
#[derive(Debug, AsBytes, FromZeroes, FromBytes, Clone, Copy)]
pub struct Direction(pub u8);
pub type StepResult = i32;
pub const IN: Direction = Direction(0);
pub const OUT: Direction = Direction(1);
pub const IN_OUT: Direction = Direction(2);
impl Default for Shared {
fn default() -> Self {
Self::new()
}
}
impl Shared {
#[must_use]
pub const fn new() -> Self {
Self {
latched_params: [0; BINDINGS_BYTES_CAP],
latched_ports: [0; BINDINGS_BYTES_CAP],
}
}
}
#[repr(C)]
#[derive(Debug, AsBytes, FromZeroes, FromBytes, Clone, Copy)]
pub struct BindingDefinition {
pub name_offset: u16,
pub flags: u8,
pub typ: u8,
pub min_size: u8,
pub max_size: Option<NonZeroU8>,
pub direction: Direction,
pub name_len: u8,
}
#[derive(Debug, Clone, Copy)]
pub struct NativeBindingDefinition<'a> {
pub name: &'a str,
pub flags: u8,
pub typ: u8,
pub min_size: u8,
pub max_size: Option<NonZeroU8>,
pub direction: Direction,
}
impl BindingDefinition {
#[must_use]
pub fn name<'a>(&self, collected_names: &'a [u8]) -> Option<&'a str> {
let offset = self.name_offset as usize;
let len = self.name_len as usize;
core::str::from_utf8(collected_names.get(offset..)?.get(..len)?).ok()
}
}
impl BindingDefinition {
#[must_use]
pub fn into_native(self, collected_names: &[u8]) -> Option<NativeBindingDefinition> {
Some(NativeBindingDefinition {
name: self.name(collected_names)?,
typ: self.typ,
flags: self.flags,
min_size: self.min_size,
max_size: self.max_size,
direction: self.direction,
})
}
}
#[cfg(test)]
mod test {
use crate::Shared;
use zerocopy::{AsBytes, FromZeroes};
#[test]
fn assert_shared_default_zeroed() {
assert_eq!(Shared::new().as_bytes(), Shared::new_zeroed().as_bytes());
assert_eq!(Shared::default().as_bytes(), Shared::new_zeroed().as_bytes());
}
}