use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Debug, thiserror::Error)]
pub enum VehicleError {
#[error("vehicle not found")]
VehicleNotFound = 256,
#[error("bogie not found")]
BogieNotFound = 512,
#[error("axle not found")]
AxleNotFound = 1024,
#[error("coupling not found")]
CouplingNotFound = 2048,
#[error("pantograph not found")]
PantographNotFound = 4096,
#[error("unknown error")]
Unknown = 0,
}
impl From<u32> for VehicleError {
fn from(value: u32) -> Self {
match value {
256 => VehicleError::VehicleNotFound,
512 => VehicleError::BogieNotFound,
1024 => VehicleError::AxleNotFound,
2048 => VehicleError::PantographNotFound,
_ => VehicleError::Unknown,
}
}
}
#[cfg(feature = "ffi")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Bogie {
index: usize,
}
#[cfg(feature = "ffi")]
impl Bogie {
pub fn get(index: usize) -> Result<Self, VehicleError> {
match unsafe { lotus_script_sys::vehicle::bogie_is_valid(index as u32) } {
0 => Ok(Self { index }),
e => Err(e.into()),
}
}
pub fn set_rail_brake_force_newton(self, value: f32) {
unsafe { lotus_script_sys::vehicle::set_rail_brake_force_newton(self.index as u32, value) };
}
}
#[cfg(feature = "ffi")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Axle {
bogie_index: usize,
axle_index: usize,
}
#[cfg(feature = "ffi")]
impl Axle {
pub fn get(bogie_index: usize, axle_index: usize) -> Result<Self, VehicleError> {
match unsafe {
lotus_script_sys::vehicle::axle_is_valid(bogie_index as u32, axle_index as u32)
} {
0 => Ok(Self {
bogie_index,
axle_index,
}),
e => Err(e.into()),
}
}
pub fn velocity_var_name(self) -> String {
format!("v_Axle_mps_{}_{}", self.bogie_index, self.axle_index)
}
pub fn bogie(self) -> Bogie {
Bogie {
index: self.bogie_index,
}
}
pub fn axle_index(self) -> usize {
self.axle_index
}
pub fn bogie_index(self) -> usize {
self.bogie_index
}
pub fn inverse_radius(self) -> f32 {
let inverse_radius = unsafe {
lotus_script_sys::vehicle::inverse_radius(
self.bogie_index as u32,
self.axle_index as u32,
)
};
assert!(!inverse_radius.is_nan());
assert_ne!(inverse_radius, f32::NEG_INFINITY);
assert_ne!(inverse_radius, f32::INFINITY);
inverse_radius
}
pub fn surface_type(self) -> SurfaceType {
let surface_type = unsafe {
lotus_script_sys::vehicle::surface_type(self.bogie_index as u32, self.axle_index as u32)
};
SurfaceType::try_from(surface_type).unwrap()
}
pub fn rail_quality(self) -> RailQuality {
let quality = unsafe {
lotus_script_sys::vehicle::rail_quality(self.bogie_index as u32, self.axle_index as u32)
};
RailQuality::try_from(quality).unwrap()
}
pub fn set_traction_force_newton(self, value: f32) {
unsafe {
lotus_script_sys::vehicle::set_traction_force_newton(
self.bogie_index as u32,
self.axle_index as u32,
value,
)
};
}
pub fn set_brake_force_newton(self, value: f32) {
unsafe {
lotus_script_sys::vehicle::set_brake_force_newton(
self.bogie_index as u32,
self.axle_index as u32,
value,
)
};
}
}
#[cfg(feature = "ffi")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Pantograph {
index: usize,
}
#[cfg(feature = "ffi")]
impl Pantograph {
pub fn get(index: usize) -> Result<Self, VehicleError> {
match unsafe { lotus_script_sys::vehicle::pantograph_is_valid(index as u32) } {
0 => Ok(Self { index }),
e => Err(e.into()),
}
}
pub fn height(self) -> f32 {
let height = unsafe { lotus_script_sys::vehicle::pantograph_height(self.index as u32) };
assert!(!height.is_nan());
assert_ne!(height, f32::INFINITY);
height
}
pub fn voltage(self) -> f32 {
let voltage = unsafe { lotus_script_sys::vehicle::pantograph_voltage(self.index as u32) };
assert!(!voltage.is_nan());
assert_ne!(voltage, f32::INFINITY);
voltage
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum RailQuality {
Smooth = 0,
Rough = 1,
FroggySmooth = 2,
FroggyRough = 3,
FlatGroove = 4,
HighSpeedSmooth = 5,
SmoothDirt = 6,
RoughDirt = 7,
Deraileur = 8,
}
impl TryFrom<u32> for RailQuality {
type Error = VehicleError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0 => Ok(RailQuality::Smooth),
1 => Ok(RailQuality::Rough),
2 => Ok(RailQuality::FroggySmooth),
3 => Ok(RailQuality::FroggyRough),
4 => Ok(RailQuality::FlatGroove),
5 => Ok(RailQuality::HighSpeedSmooth),
6 => Ok(RailQuality::SmoothDirt),
7 => Ok(RailQuality::RoughDirt),
8 => Ok(RailQuality::Deraileur),
value => Err(value.into()),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum SurfaceType {
Gravel = 0,
Street = 1,
Grass = 2,
}
impl TryFrom<u32> for SurfaceType {
type Error = VehicleError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0 => Ok(SurfaceType::Gravel),
1 => Ok(SurfaceType::Street),
2 => Ok(SurfaceType::Grass),
value => Err(value.into()),
}
}
}