rkg_utils/header/combo/
mod.rs1pub mod character;
2pub mod transmission;
3pub mod vehicle;
4pub mod weight_class;
5
6use crate::{
7 byte_handler::{ByteHandler, ByteHandlerError, FromByteHandler},
8 header::combo::{
9 character::Character,
10 transmission::Transmission,
11 vehicle::Vehicle,
12 weight_class::{GetWeightClass, WeightClass},
13 },
14};
15use std::fmt::Display;
16
17pub struct Combo {
22 character: Character,
24 vehicle: Vehicle,
26}
27
28impl Combo {
29 pub const fn get_transmission(&self) -> Transmission {
30 self.vehicle.get_transmission()
31 }
32}
33
34impl Display for Combo {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 write!(f, "{} on {}", self.character(), self.vehicle())
38 }
39}
40
41#[derive(thiserror::Error, Debug)]
43pub enum ComboError {
44 #[error("Insufficiently Long Iterator")]
46 InsufficientlyLongIterator,
47 #[error("The combo has incongruent weight classes")]
49 IncongruentWeightClasses,
50 #[error("Invalid Vehicle ID")]
52 InvalidVehicleId,
53 #[error("Invalid Character ID")]
55 InvalidCharacterId,
56 #[error("Impossible Character ID")]
58 ImpossibleCharacterId,
59 #[error("ByteHandler Error: {0}")]
61 ByteHandlerError(#[from] ByteHandlerError),
62}
63
64impl Combo {
65 #[inline(always)]
72 pub fn new(vehicle: Vehicle, character: Character) -> Result<Self, ComboError> {
73 if character.get_weight_class() != vehicle.get_weight_class() {
74 return Err(ComboError::IncongruentWeightClasses);
75 }
76
77 Ok(Self { vehicle, character })
78 }
79
80 pub const fn character(&self) -> Character {
82 self.character
83 }
84
85 pub const fn vehicle(&self) -> Vehicle {
87 self.vehicle
88 }
89}
90
91impl FromByteHandler for Combo {
100 type Err = ComboError;
101
102 fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
103 where
104 T: TryInto<ByteHandler>,
105 Self::Err: From<T::Error>,
106 {
107 let mut handler = handler.try_into()?;
108
109 handler.shift_right(2); let vehicle = handler.copy_byte(0);
111
112 handler.shift_right(2); let character = handler.copy_byte(1) & 0x3F;
114
115 Self::new(
116 Vehicle::try_from(vehicle).map_err(|_| ComboError::InvalidVehicleId)?,
117 Character::try_from(character).map_err(|_| ComboError::InvalidCharacterId)?,
118 )
119 }
120}
121
122impl GetWeightClass for Combo {
125 fn get_weight_class(&self) -> WeightClass {
126 self.character.get_weight_class()
127 }
128}