sdp_rs/lines/zone/
mod.rs

1//! Types related to the zone line (`z=`).
2
3mod zone_part;
4
5/// The zone line (`r=`) tokenizer. This is low level stuff and you shouldn't interact directly
6/// with it, unless you know what you are doing.
7pub use crate::tokenizers::time::zone::Tokenizer;
8pub use zone_part::ZonePart;
9
10use crate::Error;
11use std::convert::{TryFrom, TryInto};
12
13/// A zone line (`z=`) of SDP. It holds all the repeat zone adjustments in a `Vector`.
14#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone)]
15pub struct Zone {
16    pub parts: Vec<ZonePart>,
17}
18
19impl<'a> TryFrom<Tokenizer<'a>> for Zone {
20    type Error = Error;
21
22    fn try_from(tokenizer: Tokenizer<'a>) -> Result<Self, Self::Error> {
23        Ok(Self {
24            parts: tokenizer
25                .parts
26                .into_iter()
27                .map(TryInto::try_into)
28                .collect::<Result<Vec<_>, Error>>()?,
29        })
30    }
31}
32
33impl std::fmt::Display for Zone {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        write!(
36            f,
37            "z={}",
38            self.parts
39                .iter()
40                .map(|p| p.to_string())
41                .collect::<Vec<_>>()
42                .join(" ")
43        )
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::lines::common::TypedTime;
51    use chrono::Duration;
52
53    #[test]
54    fn from_tokenizer1() {
55        let tokenizer: Tokenizer = vec![("3730928400", "-1h"), ("3749680800", "0")].into();
56
57        assert_eq!(
58            Zone::try_from(tokenizer),
59            Ok(Zone {
60                parts: vec![
61                    ZonePart {
62                        adjustment_time: 3730928400,
63                        offset: TypedTime::Hours(Duration::hours(-1)),
64                    },
65                    ZonePart {
66                        adjustment_time: 3749680800,
67                        offset: TypedTime::None(Duration::hours(0)),
68                    }
69                ],
70            })
71        );
72    }
73
74    #[test]
75    fn display1() {
76        let zone = Zone {
77            parts: vec![
78                ZonePart {
79                    adjustment_time: 3730928400,
80                    offset: TypedTime::Hours(Duration::hours(-1)),
81                },
82                ZonePart {
83                    adjustment_time: 3749680800,
84                    offset: TypedTime::None(Duration::hours(0)),
85                },
86            ],
87        };
88
89        assert_eq!(zone.to_string(), "z=3730928400 -1h 3749680800 0");
90    }
91}