use std::ops::{Add, AddAssign, Sub, SubAssign}; pub(crate) mod syntax { use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct OutfitSpace { pub outfit: Option, pub weapon: Option, pub engine: Option, } } // TODO: user-defined space values /// Represents outfit space, either that available in a ship /// or that used by an outfit. #[derive(Debug, Clone, Copy)] pub struct OutfitSpace { /// Total available outfit space. /// This should be greater than weapon and engine. pub outfit: u32, /// Space for weapons pub weapon: u32, /// Space for engine pub engine: u32, } impl OutfitSpace { /// Make a new, zeroed OutfitSpace pub fn new() -> Self { Self { outfit: 0, weapon: 0, engine: 0, } } /// Can this outfit contain `smaller`? pub fn can_contain(&self, smaller: &Self) -> bool { self.outfit >= smaller.outfit && self.weapon >= smaller.weapon && self.engine >= smaller.engine } } impl Sub for OutfitSpace { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { OutfitSpace { outfit: self.outfit - rhs.outfit, weapon: self.weapon - rhs.weapon, engine: self.engine - rhs.engine, } } } impl SubAssign for OutfitSpace { fn sub_assign(&mut self, rhs: Self) { self.outfit -= rhs.outfit; self.weapon -= rhs.weapon; self.engine -= rhs.engine; } } impl Add for OutfitSpace { type Output = Self; fn add(self, rhs: Self) -> Self::Output { OutfitSpace { outfit: self.outfit + rhs.outfit, weapon: self.weapon + rhs.weapon, engine: self.engine + rhs.engine, } } } impl AddAssign for OutfitSpace { fn add_assign(&mut self, rhs: Self) { self.outfit += rhs.outfit; self.weapon += rhs.weapon; self.engine += rhs.engine; } } impl From for OutfitSpace { fn from(value: syntax::OutfitSpace) -> Self { Self { outfit: value.outfit.unwrap_or(0), engine: value.engine.unwrap_or(0), weapon: value.weapon.unwrap_or(0), } } }