use std::{ fmt::{Debug, Display}, ops::{Add, AddAssign, Div, Mul, Sub, SubAssign}, }; use binrw::{binrw, BinRead, BinWrite}; use diff::{Diff, VecDiff}; use num_enum::{IntoPrimitive, TryFromPrimitive}; use rand::{thread_rng, Rng}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use strum::EnumIter; use crate::{array_of::ArrayOfPrimitive, field_of::FieldOf}; /// Generic field with structure of length + data pub type Field = ArrayOfPrimitive; pub type U16 = FieldOf; pub type I16 = FieldOf; pub type U32 = FieldOf; pub type I32 = FieldOf; pub type F64 = FieldOf; pub type Bool = FieldOf; impl From> for bool { fn from(value: FieldOf) -> Self { value.value != 0 } } impl From for FieldOf { fn from(value: bool) -> Self { Self { value: match value { true => 1, false => 0, }, } } } #[binrw] #[derive(Clone, Default, PartialEq)] pub struct WString { // Temporary variable that holds number of elements #[br(temp)] #[bw(try_calc(u32::try_from(value.len() * core::mem::size_of::())))] size: u32, #[br(count = size / core::mem::size_of::() as u32)] pub value: Vec, } impl From<&WString> for String { fn from(value: &WString) -> Self { String::from_utf16_lossy(&value.value) } } impl From for WString { fn from(value: String) -> Self { let value: Vec = value.encode_utf16().collect(); Self { value } } } // Custom Diff implementation to only diff internal value impl Diff for WString { type Repr = VecDiff; fn diff(&self, other: &Self) -> Self::Repr { self.value.diff(&other.value) } fn apply(&mut self, diff: &Self::Repr) { self.value.apply(diff) } fn identity() -> Self { Self { value: vec![] } } } impl Debug for WString { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "\"{}\"", String::from(self)) } } impl Display for WString { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", String::from(self)) } } #[derive(Clone, Debug, Default, Diff, PartialEq, BinRead, BinWrite)] #[diff(attr( #[derive(Debug, PartialEq)] ))] pub struct Rgba { pub red: u8, pub green: u8, pub blue: u8, pub alpha: u8, } impl From<(u8, u8, u8)> for Rgba { fn from(value: (u8, u8, u8)) -> Self { Self { red: value.0, green: value.1, blue: value.2, alpha: 0, } } } impl Rgba { pub fn random() -> Self { Self { red: thread_rng().gen(), green: thread_rng().gen(), blue: thread_rng().gen(), alpha: 0, } } } #[derive( Copy, Clone, Debug, Default, Diff, PartialEq, BinRead, BinWrite, Serialize, Deserialize, )] #[diff(attr( #[derive(Debug, PartialEq)] ))] #[serde(rename_all = "PascalCase")] pub struct Coordinate { pub x: f64, pub y: f64, } impl Display for Coordinate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "({:.2}, {:.2})", self.x, self.y) } } impl Sub for Coordinate { type Output = Coordinate; fn sub(self, rhs: Self) -> Self::Output { Coordinate { x: self.x - rhs.x, y: self.y - rhs.y, } } } impl SubAssign for Coordinate { fn sub_assign(&mut self, rhs: Self) { self.x -= rhs.x; self.y -= rhs.y; } } impl Add for Coordinate { type Output = Coordinate; fn add(self, rhs: Self) -> Self::Output { Coordinate { x: self.x + rhs.x, y: self.y + rhs.y, } } } impl AddAssign for Coordinate { fn add_assign(&mut self, rhs: Self) { self.x += rhs.x; self.y += rhs.y; } } impl Mul for Coordinate { type Output = Coordinate; fn mul(self, rhs: Self) -> Self::Output { Coordinate { x: self.x * rhs.x, y: self.y * rhs.y, } } } impl Div for Coordinate { type Output = Coordinate; fn div(self, rhs: Self) -> Self::Output { Coordinate { x: self.x / rhs.x, y: self.y / rhs.y, } } } impl From<(f64, f64)> for Coordinate { fn from(value: (f64, f64)) -> Self { Self { x: value.0, y: value.1, } } } #[derive(Clone, Debug, Diff, PartialEq, BinRead, BinWrite, strum::Display)] #[diff(attr( #[derive(Debug, PartialEq)] ))] #[brw(repr(u32))] #[repr(u32)] pub enum WobbleType { Spiral = 0, Sinusoidal = 1, Ellipse = 2, Vert8 = 3, Hori8 = 4, Unknown = 5, } impl Default for WobbleType { fn default() -> Self { WobbleType::Unknown } } #[derive(Clone, Debug, Diff, PartialEq, BinRead, BinWrite, strum::Display)] #[diff(attr( #[derive(Debug, PartialEq)] ))] #[brw(repr(u16))] #[repr(u16)] pub enum ObjectType { Unknown = 0, Curve = 1, Point = 2, Rectangle = 3, Circle = 4, Ellipse = 5, Polygon = 6, HatchLine = 16, Hatch = 32, } impl Default for ObjectType { fn default() -> Self { ObjectType::Unknown } } #[derive( Copy, Clone, Debug, Diff, PartialEq, strum::Display, Serialize_repr, Deserialize_repr, EnumIter, IntoPrimitive, TryFromPrimitive, )] #[diff(attr( #[derive(Debug, PartialEq)] ))] #[repr(u32)] pub enum PulseWidth { Ns2 = 2, Ns4 = 4, Ns6 = 6, Ns8 = 8, Ns12 = 12, Ns20 = 20, Ns30 = 30, Ns45 = 45, Ns60 = 60, Ns80 = 80, Ns100 = 100, Ns150 = 150, Ns200 = 200, Ns250 = 250, Ns350 = 350, Ns500 = 500, }