1use crate::error::ParsingError;
2
3#[derive(Debug, Default, Clone, PartialEq)]
6pub struct ProductionAttributes {
7 pub satellite: String,
9
10 pub year: u32,
12
13 pub doy: u32,
15
16 #[cfg(feature = "flate2")]
18 #[cfg_attr(docsrs, doc(cfg(feature = "flate2")))]
19 pub gzip_compressed: bool,
20}
21
22impl std::fmt::Display for ProductionAttributes {
23 #[cfg(not(feature = "flate2"))]
24 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
25 let sat_len = self.satellite.len();
26 let mut sat_name = self.satellite[..std::cmp::min(sat_len, 5)].to_string();
27
28 for _ in sat_len..5 {
29 sat_name.push('X');
30 }
31
32 write!(f, "{}{:02}{:03}", sat_name, self.year - 2000, self.doy)
33 }
34
35 #[cfg(feature = "flate2")]
36 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37 let sat_len = self.satellite.len();
38 let mut sat_name = self.satellite[..std::cmp::min(sat_len, 5)].to_string();
39
40 for _ in sat_len..5 {
41 sat_name.push('X');
42 }
43
44 let mut extension = "".to_string();
45
46 if self.gzip_compressed {
47 extension.push_str(".gz");
48 }
49
50 write!(
51 f,
52 "{}{:02}{:03}{}",
53 sat_name,
54 self.year - 2000,
55 self.doy,
56 extension
57 )
58 }
59}
60
61impl std::str::FromStr for ProductionAttributes {
62 type Err = ParsingError;
63
64 fn from_str(filename: &str) -> Result<Self, Self::Err> {
65 let filename = filename.to_uppercase();
66
67 let name_len = filename.len();
68
69 if name_len != 10 && name_len != 13 {
70 return Err(ParsingError::NonStandardFileName);
71 }
72
73 let mut doy = 0;
74 let mut year = 2000;
75
76 let satellite = filename[..5].to_string();
77
78 if let Ok(y) = filename[5..7].parse::<u32>() {
79 year += y;
80 }
81
82 if let Ok(day) = filename[7..10].parse::<u32>() {
83 doy = day;
84 }
85
86 Ok(Self {
87 satellite,
88 year,
89 doy,
90 #[cfg(feature = "flate2")]
91 gzip_compressed: filename.ends_with(".GZ"),
92 })
93 }
94}
95
96#[cfg(test)]
97mod test {
98 use super::*;
99 use std::str::FromStr;
100
101 #[test]
102 #[cfg(feature = "flate2")]
103 fn test_prod_attributes() {
104 for (filename, sat_name, year, doy, gzip_compressed) in [
105 ("cs2rx18164", "CS2RX", 2018, 164, false),
106 ("cs2rx18164.gz", "CS2RX", 2018, 164, true),
107 ] {
108 let prod = ProductionAttributes::from_str(filename).unwrap_or_else(|e| {
109 panic!("Failed to \"{}\": {}", filename, e);
110 });
111
112 assert_eq!(prod.satellite, sat_name);
113 assert_eq!(prod.year, year);
114 assert_eq!(prod.doy, doy);
115 assert_eq!(prod.gzip_compressed, gzip_compressed);
116 }
117 }
118}