sdp_rs/lines/zone/
zone_part.rs

1use crate::{lines::common::TypedTime, Error};
2use std::convert::{TryFrom, TryInto};
3
4pub use crate::tokenizers::time::zone_part::Tokenizer;
5
6/// A zone part is part of the zone line ([super::Zone]). It holds the adjustment time and the
7/// offset of that adjustment time.
8#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Copy)]
9pub struct ZonePart {
10    pub adjustment_time: u64,
11    pub offset: TypedTime,
12}
13
14impl<'a> TryFrom<Tokenizer<'a>> for ZonePart {
15    type Error = Error;
16
17    fn try_from(tokenizer: Tokenizer<'a>) -> Result<Self, Self::Error> {
18        Ok(Self {
19            adjustment_time: tokenizer.adjustment.parse().map_err(|e| {
20                Self::Error::parser_with_error("zone adjustment time", tokenizer.adjustment, e)
21            })?,
22            offset: tokenizer
23                .offset
24                .try_into()
25                .map_err(|e| Self::Error::parser_with_error("zone offset", tokenizer.offset, e))?,
26        })
27    }
28}
29
30impl std::fmt::Display for ZonePart {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        write!(f, "{} {}", self.adjustment_time, self.offset)
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use chrono::Duration;
40
41    #[test]
42    fn from_tokenizer1() {
43        let tokenizer: Tokenizer = ("604800", "3600").into();
44
45        assert_eq!(
46            ZonePart::try_from(tokenizer),
47            Ok(ZonePart {
48                adjustment_time: 604800,
49                offset: TypedTime::None(Duration::seconds(3600)),
50            })
51        );
52    }
53
54    #[test]
55    fn from_tokenizer2() {
56        let tokenizer: Tokenizer = ("604800", "-3h").into();
57
58        assert_eq!(
59            ZonePart::try_from(tokenizer),
60            Ok(ZonePart {
61                adjustment_time: 604800,
62                offset: TypedTime::Hours(Duration::hours(-3)),
63            })
64        );
65    }
66
67    #[test]
68    fn display1() {
69        let zone_part = ZonePart {
70            adjustment_time: 604800,
71            offset: TypedTime::Hours(Duration::hours(-3)),
72        };
73
74        assert_eq!(zone_part.to_string(), "604800 -3h");
75    }
76}