rtzlib/
shared.rs

1//! Shared functionality for the `rtz` crate.
2
3#[cfg(any(feature = "admin-osm", feature = "tz-ned", feature = "tz-osm"))]
4use serde::{Deserialize, Serialize};
5
6#[cfg(feature = "web")]
7use utoipa::ToSchema;
8
9#[cfg(feature = "admin-osm")]
10use rtz_core::geo::admin::osm::OsmAdmin;
11#[cfg(feature = "tz-ned")]
12use rtz_core::geo::tz::ned::NedTimezone;
13#[cfg(feature = "tz-osm")]
14use rtz_core::geo::tz::osm::OsmTimezone;
15
16/// The response type for the NED timezone endpoint when found.
17///
18/// Currently ingested version of this data set is [here](https://github.com/nvkelso/natural-earth-vector/blob/master/geojson/ne_10m_time_zones.geojson).
19#[cfg(feature = "tz-ned")]
20#[derive(Debug, Serialize, Deserialize)]
21#[cfg_attr(feature = "web", derive(ToSchema))]
22#[serde(rename_all = "camelCase")]
23pub struct NedTimezoneResponse1 {
24    /// The index of the [`NedTimezoneResponse1`] in the global static cache.
25    ///
26    /// This is is not stable across builds or new data sets.  It is merely unique during a single build.
27    pub id: usize,
28    /// The `identifier` of the [`NedTimezoneResponse1`] (e.g., `America/Los_Angeles`).
29    ///
30    /// Essentially, it is the IANA TZ identifier.
31    pub identifier: Option<&'static str>,
32
33    /// The `description` of the [`NedTimezoneResponse1`] (e.g., the countries affected).
34    pub description: &'static str,
35    /// The `dst_description` of the [`NedTimezoneResponse1`] (i.e., daylight savings time information).
36    pub dst_description: Option<&'static str>,
37
38    /// The `offset_str` of the [`NedTimezoneResponse1`] (e.g., `UTC-8:00`).
39    pub offset: &'static str,
40
41    /// The `zone_num` of the [`NedTimezoneResponse1`] (e.g., `-8`).
42    pub zone: f32,
43    /// The `raw_offset` of the [`NedTimezoneResponse1`] (e.g., `-28800`).
44    pub raw_offset: i32,
45}
46
47#[cfg(feature = "tz-ned")]
48impl From<&'static NedTimezone> for NedTimezoneResponse1 {
49    fn from(value: &'static NedTimezone) -> NedTimezoneResponse1 {
50        NedTimezoneResponse1 {
51            id: value.id,
52            identifier: value.identifier.as_deref(),
53            description: value.description.as_ref(),
54            dst_description: value.dst_description.as_deref(),
55            offset: value.offset.as_ref(),
56            zone: value.zone,
57            raw_offset: value.raw_offset,
58        }
59    }
60}
61
62/// The response type for the OSM timezone endpoint when found.
63///
64/// Currently ingested version of this data set is [here](https://github.com/evansiroky/timezone-boundary-builder/releases/download/2023b/timezones-with-oceans.geojson.zip).
65#[cfg(feature = "tz-osm")]
66#[derive(Debug, Serialize, Deserialize)]
67#[cfg_attr(feature = "web", derive(ToSchema))]
68#[serde(rename_all = "camelCase")]
69pub struct OsmTimezoneResponse1 {
70    /// The index of the [`OsmTimezoneResponse1`] in the global static cache.
71    ///
72    /// This is is not stable across builds or new data sets.  It is merely unique during a single build.
73    pub id: usize,
74    /// The `identifier` of the [`OsmTimezoneResponse1`] (e.g., `America/Los_Angeles`).
75    ///
76    /// Essentially, it is the IANA TZ identifier.
77    pub identifier: &'static str,
78    /// The `short_identifier` of the [`OsmTimezoneResponse1`] (e.g., `PDT`).
79    pub short_identifier: String,
80
81    /// The `offset` of the [`OsmTimezoneResponse1`] (e.g., `UTC-8:00`).
82    pub offset: String,
83
84    /// The `raw_offset` of the [`OsmTimezoneResponse1`] (e.g., `-28800`).
85    pub raw_offset: i32,
86    /// The `raw_base_offset` of the [`OsmTimezoneResponse1`] (e.g., `-28800`).
87    pub raw_base_offset: i32,
88    /// The `raw_dst_offset` of the [`OsmTimezoneResponse1`] (e.g., `-28800`).
89    pub raw_dst_offset: i32,
90
91    /// The `zone_num` of the [`OsmTimezoneResponse1`] (e.g., `-8`).
92    pub zone: f32,
93
94    /// The current time in the timezone.
95    pub current_time: String,
96}
97
98#[cfg(feature = "tz-osm")]
99impl From<&'static OsmTimezone> for OsmTimezoneResponse1 {
100    fn from(value: &'static OsmTimezone) -> OsmTimezoneResponse1 {
101        use chrono::{Offset, Utc};
102        use chrono_tz::{OffsetComponents, Tz};
103
104        let tz: Tz = value.identifier.parse().unwrap();
105        let time = Utc::now().with_timezone(&tz);
106        let tz_offset = time.offset();
107        let fixed_offset = tz_offset.fix();
108
109        let short_identifier = tz_offset.to_string();
110
111        let offset = format!("UTC{}", fixed_offset);
112        let raw_offset = fixed_offset.local_minus_utc();
113        let raw_base_offset = tz_offset.base_utc_offset().num_seconds() as i32;
114        let raw_dst_offset = tz_offset.dst_offset().num_seconds() as i32;
115
116        let zone = raw_offset as f32 / 3600.0;
117
118        let current_time = time.to_rfc3339();
119
120        OsmTimezoneResponse1 {
121            id: value.id,
122            identifier: value.identifier.as_ref(),
123            short_identifier,
124            offset,
125            raw_offset,
126            raw_base_offset,
127            raw_dst_offset,
128            zone,
129            current_time,
130        }
131    }
132}
133
134/// The response type for the [`OsmAdmin`] endpoint when found.
135///
136/// Currently ingested version of this data set is [here](https://planet.openstreetmap.org/).
137#[cfg(feature = "admin-osm")]
138#[derive(Debug, Serialize, Deserialize)]
139#[cfg_attr(feature = "web", derive(ToSchema))]
140#[serde(rename_all = "camelCase")]
141pub struct OsmAdminResponse1 {
142    /// The index of the [`OsmAdminResponse1`] in the global static cache.
143    ///
144    /// This is is not stable across builds or new data sets.  It is merely unique during a single build.
145    pub id: usize,
146
147    /// The `name` of the [`OsmAdminResponse1`] (e.g., `France`).
148    pub name: &'static str,
149
150    /// The `admin_level` of the [`OsmAdminResponse1`] (e.g., `2`).
151    pub level: usize,
152}
153
154#[cfg(feature = "admin-osm")]
155impl From<&'static OsmAdmin> for OsmAdminResponse1 {
156    fn from(value: &'static OsmAdmin) -> OsmAdminResponse1 {
157        OsmAdminResponse1 {
158            id: value.id,
159            name: value.name.as_ref(),
160            level: value.level,
161        }
162    }
163}