Skip to main content

rkg_utils/header/
transmission_mod.rs

1use std::{convert::Infallible, fmt::Display};
2
3use crate::byte_handler::{ByteHandler, ByteHandlerError, FromByteHandler};
4
5/// Errors that can occur while constructing a [`TransmissionMod`].
6#[derive(thiserror::Error, Debug)]
7pub enum TransmissionModError {
8    /// The transmission mod ID byte did not map to any known [`TransmissionMod`] variant.
9    #[error("Invalid transmission mod ID")]
10    InvalidTransmissionMod,
11    /// A `ByteHandler` operation failed.
12    #[error("ByteHandler Error: {0}")]
13    ByteHandlerError(#[from] ByteHandlerError),
14    /// Infallible conversion error; cannot occur at runtime.
15    #[error("")]
16    Infallible(#[from] Infallible),
17}
18
19/// The drift transmission modifier applied to a Retro Rewind (Pulsar) ghost.
20///
21/// Retro Rewind supports server-side transmission overrides that force all
22/// vehicles into a specific drift mode, overriding the per-vehicle default.
23/// `Vanilla` indicates no override is active.
24#[derive(Clone, Copy, Debug, PartialEq)]
25pub enum TransmissionMod {
26    /// No transmission override; vehicles use their default drift behavior.
27    Vanilla,
28    /// All vehicles (both karts and bikes) are forced to inside drift.
29    AllInside,
30    /// All bikes (but not karts) are forced to inside drift.
31    AllBikeInside,
32    /// All vehicles (both karts and bikes) are forced to outside drift.
33    AllOutside,
34}
35
36/// Converts a raw byte value into a [`TransmissionMod`].
37///
38/// # Errors
39///
40/// Returns [`TransmissionModError::InvalidTransmissionMod`] if the byte does
41/// not correspond to a known variant (valid range is `0x00`–`0x03`).
42impl TryFrom<u8> for TransmissionMod {
43    type Error = TransmissionModError;
44
45    fn try_from(value: u8) -> Result<Self, Self::Error> {
46        match value {
47            0x00 => Ok(Self::Vanilla),
48            0x01 => Ok(Self::AllInside),
49            0x02 => Ok(Self::AllBikeInside),
50            0x03 => Ok(Self::AllOutside),
51            _ => Err(TransmissionModError::InvalidTransmissionMod),
52        }
53    }
54}
55
56/// Converts a [`TransmissionMod`] into its raw byte representation.
57impl From<TransmissionMod> for u8 {
58    fn from(value: TransmissionMod) -> Self {
59        match value {
60            TransmissionMod::Vanilla => 0x00,
61            TransmissionMod::AllInside => 0x01,
62            TransmissionMod::AllBikeInside => 0x02,
63            TransmissionMod::AllOutside => 0x03,
64        }
65    }
66}
67
68/// Deserializes a [`TransmissionMod`] from header byte `0x0C`.
69impl FromByteHandler for TransmissionMod {
70    type Err = TransmissionModError;
71
72    fn from_byte_handler<T>(handler: T) -> Result<Self, Self::Err>
73    where
74        T: TryInto<ByteHandler>,
75        Self::Err: From<T::Error>,
76    {
77        ((handler.try_into()?.copy_byte(0) >> 1) & 0x03).try_into()
78    }
79}
80
81/// Formats the transmission mod as a human-readable name.
82impl Display for TransmissionMod {
83    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84        match self {
85            Self::Vanilla => write!(f, "Vanilla"),
86            Self::AllInside => write!(f, "All Inside"),
87            Self::AllBikeInside => write!(f, "All Bikes Inside"),
88            Self::AllOutside => write!(f, "All Outside"),
89        }
90    }
91}