knuckles_parse/records/
scalen.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4#[cfg(feature = "python")]
5use pyo3::prelude::*;
6
7#[cfg(feature = "python")]
8use knuckles_macro::pydefault;
9
10#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[cfg_attr(feature = "python", pyclass)]
13#[cfg_attr(feature = "python", pydefault)]
14pub enum ScaleN {
15    Scale1(ScalenRecord),
16    Scale2(ScalenRecord),
17    Scale3(ScalenRecord),
18}
19
20impl ScaleN {
21    pub fn new(str: &str) -> Self {
22        let record = ScalenRecord::from(str);
23        match record.n {
24            1 => ScaleN::Scale1(record),
25            2 => ScaleN::Scale2(record),
26            3 => ScaleN::Scale3(record),
27            _ => panic!("Invalid SCALEn record"),
28        }
29    }
30}
31
32impl From<&str> for ScaleN {
33    fn from(str: &str) -> Self {
34        ScaleN::new(str)
35    }
36}
37
38#[derive(Debug, Clone)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
41#[cfg_attr(feature = "python", pydefault)]
42pub struct ScalenRecord {
43    pub n: u16,
44    pub scalen: [f32; 3],
45    pub un: f32,
46}
47
48impl ScalenRecord {
49    pub fn new(str: &str) -> ScalenRecord {
50        ScalenRecord {
51            n: str.chars().nth(5).unwrap() as u16 - 48,
52            scalen: [
53                str[10..20].trim().parse().unwrap_or_default(),
54                str[20..30].trim().parse().unwrap_or_default(),
55                str[30..40].trim().parse().unwrap_or_default(),
56            ],
57            un: str[45..55].trim().parse().unwrap_or_default(),
58        }
59    }
60}
61
62impl From<&str> for ScalenRecord {
63    fn from(str: &str) -> Self {
64        ScalenRecord::new(str)
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    #[test]
72    fn parse_scalen_line_test() {
73        const LINE: &str =
74            "SCALE1      0.019231  0.000000  0.000000        0.00000                         ";
75        let record = ScalenRecord::new(LINE);
76        assert_eq!(record.n, 1);
77        assert_eq!(record.scalen, [0.019231, 0.0, 0.0]);
78        assert_eq!(record.un, 0.0);
79    }
80
81    #[test]
82    fn parse_scalen_test() {
83        const LINE: &str =
84            "SCALE1      0.019231  0.000000  0.000000        0.00000                         ";
85        let record = ScaleN::new(LINE);
86        match record {
87            ScaleN::Scale1(record) => {
88                assert_eq!(record.n, 1);
89                assert_eq!(record.scalen, [0.019231, 0.0, 0.0]);
90                assert_eq!(record.un, 0.0);
91            }
92            _ => panic!("Wrong record type"),
93        }
94    }
95}