use core::ops::{Add, AddAssign, Deref, Sub, SubAssign}; use defmt::Format; use packed_struct::PackedStruct; /// wrapper type because packed_struct doesn't implement float /// packing by default #[derive(Debug, Format, Clone, Default, Copy)] pub struct PackedFloat(pub f32); impl Add for PackedFloat { type Output = Self; fn add(self, rhs: Self) -> Self::Output { Self(self.0 + rhs.0) } } impl Add for PackedFloat { type Output = Self; fn add(self, rhs: f32) -> Self::Output { Self(self.0 + rhs) } } impl Sub for PackedFloat { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { Self(self.0 - rhs.0) } } impl Sub for PackedFloat { type Output = Self; fn sub(self, rhs: f32) -> Self::Output { Self(self.0 - rhs) } } impl SubAssign for PackedFloat { fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0; } } impl SubAssign for PackedFloat { fn sub_assign(&mut self, rhs: f32) { self.0 -= rhs; } } impl AddAssign for PackedFloat { fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0; } } impl AddAssign for PackedFloat { fn add_assign(&mut self, rhs: f32) { self.0 += rhs; } } pub trait ToRegularArray { fn to_regular_array(&self) -> &[f32; T]; } impl ToRegularArray for [PackedFloat; T] { fn to_regular_array(&self) -> &[f32; T] { unsafe { &*(self as *const _ as *const _) } } } pub trait ToPackedFloatArray { fn to_packed_float_array(&self) -> &[PackedFloat; T]; } impl ToPackedFloatArray for [f32; T] { fn to_packed_float_array(&self) -> &[PackedFloat; T] { unsafe { &*(self as *const _ as *const _) } } } impl PackedStruct for PackedFloat { type ByteArray = [u8; 4]; fn pack(&self) -> packed_struct::PackingResult { Ok(self.to_be_bytes()) } fn unpack(src: &Self::ByteArray) -> packed_struct::PackingResult { Ok(Self(f32::from_be_bytes(*src))) } } impl Deref for PackedFloat { type Target = f32; fn deref(&self) -> &Self::Target { &self.0 } } impl From for PackedFloat { fn from(f: f32) -> Self { Self(f) } } #[derive(Debug, Clone, Format, Default, Copy)] pub struct XyValuePair { pub x: T, pub y: T, }