altrios_core/track/link/speed/
speed_param.rs

1use crate::imports::*;
2
3#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
4#[repr(u8)]
5pub enum LimitType {
6    //CivilSpeed = 1,
7    //MaxPermissibleSpeed = 2,
8    MassTotal = 3,
9    #[default]
10    MassPerBrake = 4,
11    AxleCount = 5,
12}
13
14impl Valid for LimitType {}
15
16#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
17#[repr(u8)]
18pub enum CompareType {
19    #[default]
20    TpEqualRp = 1,
21    TpGreaterThanRp = 2,
22    TpLessThanRp = 3,
23    TpGreaterThanEqualRp = 4,
24    TpLessThanEqualRp = 5,
25}
26
27impl CompareType {
28    pub fn applies<T>(&self, train_param: T, limit_param: T) -> bool
29    where
30        T: PartialEq + PartialOrd,
31    {
32        match self {
33            Self::TpEqualRp => train_param == limit_param,
34            Self::TpGreaterThanRp => train_param > limit_param,
35            Self::TpLessThanRp => train_param < limit_param,
36            Self::TpGreaterThanEqualRp => train_param >= limit_param,
37            Self::TpLessThanEqualRp => train_param <= limit_param,
38        }
39    }
40}
41
42impl Valid for CompareType {
43    fn valid() -> Self {
44        Self::TpGreaterThanRp
45    }
46}
47
48#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq)]
49pub struct SpeedParam {
50    pub limit_val: f64,
51    pub limit_type: LimitType,
52    pub compare_type: CompareType,
53}
54
55impl Valid for SpeedParam {
56    fn valid() -> Self {
57        Self {
58            limit_val: (100.0 * uc::TON).value,
59            limit_type: LimitType::valid(),
60            compare_type: CompareType::valid(),
61        }
62    }
63}
64
65impl ObjState for SpeedParam {
66    fn validate(&self) -> ValidationResults {
67        let mut errors = ValidationErrors::new();
68        if let None | Some(Ordering::Less) = self.limit_val.partial_cmp(&0.0) {
69            errors.push(anyhow!(
70                "Limit val for {:?} = {:?} must be a positive number",
71                self.limit_type,
72                self.limit_val,
73            ));
74        }
75        if self.limit_type == LimitType::AxleCount && self.limit_val.trunc() != self.limit_val {
76            errors.push(anyhow!(
77                "Limit val for {:?} = {:?} must also be an integer!",
78                self.limit_type,
79                self.limit_val
80            ));
81        }
82        errors.make_err()
83    }
84}
85
86impl ObjState for Vec<SpeedParam> {
87    fn is_fake(&self) -> bool {
88        (**self).is_fake()
89    }
90    fn validate(&self) -> ValidationResults {
91        (**self).validate()
92    }
93}
94
95impl Valid for Vec<SpeedParam> {}
96
97impl ObjState for [SpeedParam] {
98    fn validate(&self) -> ValidationResults {
99        let mut errors = ValidationErrors::new();
100        validate_slice_real(&mut errors, self, "Speed param");
101        early_err!(errors, "Speed params");
102        if self.windows(2).any(|w| w[0] == w[1]) {
103            errors.push(anyhow!("Speed params must be unique!"));
104        }
105        errors.make_err()
106    }
107}
108
109#[cfg(test)]
110mod test_speed_param {
111    use super::*;
112    use crate::testing::*;
113
114    impl Cases for SpeedParam {}
115    check_cases!(SpeedParam);
116}
117
118#[cfg(test)]
119mod test_speed_params {
120    use super::*;
121    use crate::testing::*;
122
123    impl Cases for Vec<SpeedParam> {
124        fn real_cases() -> Vec<Self> {
125            vec![Self::valid(), vec![SpeedParam::valid()]]
126        }
127    }
128    check_cases!(Vec<SpeedParam>);
129    check_vec_elems!(SpeedParam);
130    check_vec_duplicates!(SpeedParam);
131}