api_tools/value_objects/
timezone.rs

1//! Timezone value object representation
2
3use chrono_tz::Tz;
4use std::fmt::Display;
5use std::str::FromStr;
6use thiserror::Error;
7
8#[derive(Debug, Clone, PartialEq, Error)]
9pub enum TimezoneError {
10    #[error("Invalid timezone: {0}")]
11    Invalid(String),
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct Timezone {
16    value: Tz,
17}
18
19impl Timezone {
20    /// Create a new timezone
21    pub fn new(tz: Tz) -> Self {
22        Self { value: tz }
23    }
24}
25
26impl TryFrom<&str> for Timezone {
27    type Error = TimezoneError;
28
29    fn try_from(value: &str) -> Result<Self, Self::Error> {
30        let tz = Tz::from_str(value).map_err(|e| TimezoneError::Invalid(e.to_string()))?;
31
32        Ok(Self::new(tz))
33    }
34}
35
36impl Display for Timezone {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        write!(f, "{}", self.value)
39    }
40}
41
42impl Default for Timezone {
43    fn default() -> Self {
44        Self::new(Tz::Europe__Paris)
45    }
46}
47
48#[cfg(test)]
49mod test {
50    use super::*;
51    use chrono_tz::Tz::Europe__Paris;
52
53    #[test]
54    fn test_try_from_str() {
55        let tz = Timezone::try_from("Europe/Paris").unwrap();
56        assert_eq!(tz.value, Europe__Paris);
57
58        let tz = Timezone::try_from("Invalid");
59        assert!(tz.is_err());
60    }
61
62    #[test]
63    fn test_display() {
64        let tz = Timezone::new(Europe__Paris);
65        assert_eq!(tz.to_string(), "Europe/Paris");
66    }
67
68    #[test]
69    fn test_default() {
70        let tz = Timezone::default();
71        assert_eq!(tz.value, Europe__Paris);
72    }
73}