micrortu_ie_base/
iebuf.rs

1use zerocopy::{IntoBytes, FromBytes, FromZeros};
2
3use crate::SmallIE;
4use core::mem::size_of;
5
6static_assertions::assert_eq_size!(SmallIE, IEBuf);
7static_assertions::assert_eq_align!(SmallIE, IEBuf);
8
9#[repr(C)]
10#[derive(Default, Debug, Clone, Copy, PartialEq, IntoBytes, FromBytes)]
11pub struct IEBuf(pub [u8; size_of::<SmallIE>()]);
12
13impl IEBuf {
14    #[must_use]
15    pub fn is_valid(self) -> bool {
16        SmallIE::default_for_typecode(self.0[0]).is_some()
17    }
18
19    #[must_use]
20    pub fn terminator() -> Self {
21        Self([0; size_of::<SmallIE>()])
22    }
23}
24
25#[derive(Default, Debug, Clone, Copy, PartialEq)]
26pub struct IEDeserializationError;
27
28impl TryFrom<IEBuf> for SmallIE {
29    type Error = IEDeserializationError;
30    fn try_from(value: IEBuf) -> Result<Self, Self::Error> {
31        let mut new = Self::default_for_typecode(value.0[0]).ok_or(IEDeserializationError)?;
32        let bytes = &value.0[1..];
33        let target = new.as_mut_bytes();
34        target.copy_from_slice(&bytes[..target.len()]);
35
36        Ok(new)
37    }
38}
39
40impl TryFrom<&IEBuf> for &SmallIE {
41    type Error = IEDeserializationError;
42
43    #[allow(clippy::ptr_as_ptr)]
44    fn try_from(value: &IEBuf) -> Result<Self, Self::Error> {
45        SmallIE::default_for_typecode(value.0[0]).ok_or(IEDeserializationError)?;
46
47        let ptr = core::ptr::from_ref(value) as *const _;
48
49        Ok(unsafe { &*ptr })
50    }
51}
52
53impl TryFrom<&mut IEBuf> for &mut SmallIE {
54    type Error = IEDeserializationError;
55
56    #[allow(clippy::ptr_as_ptr)]
57    fn try_from(value: &mut IEBuf) -> Result<Self, Self::Error> {
58        SmallIE::default_for_typecode(value.0[0]).ok_or(IEDeserializationError)?;
59
60        let ptr = core::ptr::from_mut(value) as *mut _;
61
62        Ok(unsafe { &mut *ptr })
63    }
64}
65
66impl From<SmallIE> for IEBuf {
67    #[inline]
68    fn from(value: SmallIE) -> Self {
69        let d = value.typecode();
70        let mut this = Self::new_zeroed();
71        let bytes = Self::as_mut_bytes(&mut this);
72        bytes[0] = d;
73        value
74            .copy_to_slice(&mut bytes[1..])
75            .expect("Space should be sufficient");
76        this
77    }
78}