airports/
lib.rs

1//! Easy mapping between IATA airport codes and timezones + cooridnates.
2//!
3//! Provides mappings between IATA airport codes like "LHR" / "SFO" to
4//! non-abbreviated timezone name like "Europe/London". Also includes
5//! ability to get DateTime object in the given time zone for convience.
6//!
7//! Actual mapping has been assambled from various sources available online
8//! and spot check validated of around 400 locations.
9//!
10//! ## Examples
11//!
12//! Fetch time zone string of the LHR (London) airport.
13//!
14//! ```
15//! use airports::Airports;
16//!
17//! fn main() {
18//!    let db = Airports::new();
19//!    println!("lhr: {:?}", db.get_tz_name("lhr"));
20//!    println!("LHR: {:?}", db.get_tz_name("LHR"));
21//!    println!("SOMETHING: {:?}", db.get_tz_name("SOMETHING"));
22//! }
23//! ```
24//!
25//! Which produces the following output:
26//! ```
27//! lhr: Some("Europe/London")
28//! LHR: Some("Europe/London")
29//! SOMETHING: None
30//! ```
31//!
32//! The get_tz function returns Option on Tz allowing easy check
33//! of time in the given airport location. See examples/ for more details.
34//!
35//! ```
36//!    let db = Airports::new();
37//!    let x: DateTime<Tz>= Utc::now().with_timezone(&db.get_tz("SFO").unwrap());
38//!    println!("Time in SFO: {}", x);
39//! ```
40//! ```
41//! Time in SFO: 2022-06-28 08:27:11.605433 PDT
42//! ```
43
44//#![warn(missing_docs)]
45use chrono_tz::Tz;
46use std::collections::BTreeMap;
47
48#[derive(Clone, Debug)]
49pub struct Airports {
50    db: BTreeMap<String, String>,
51}
52
53impl Default for Airports {
54    fn default() -> Self {
55        Self::new()
56    }
57}
58
59impl Airports {
60    pub fn new() -> Self {
61        let db: &'static str = include_str!("airports.yaml");
62        let ddb: BTreeMap<String, String> = serde_yaml::from_str(db).unwrap();
63        Airports { db: ddb }
64    }
65
66    /// Returns an Option on String, with String containing the timezone name,
67    /// or None if mapping not found.
68    ///
69    /// # Example
70    ///
71    /// ```
72    /// let lhr_timezone = db.get_tz_name("LHR");
73    /// ```
74    pub fn get_tz_name(&self, code: &str) -> Option<&String> {
75        self.db.get(&code.to_uppercase())
76    }
77
78    /// Returns an Option on Tz (from chrono_tz) for given IATA airport code.
79    /// This can be then passed to chrono/DataTime to get time using specific
80    /// time zone.
81    ///
82    /// # Example
83    ///
84    /// use airports::Airports;
85    /// use chrono::{DateTime, Utc};
86    /// use chrono_tz::Tz;
87    ///
88    /// fn main() {
89    ///    let db = Airports::new();
90    ///    let x: DateTime<Tz>= Utc::now().with_timezone(&db.get_tz("SFO").unwrap());
91    ///    println!("Time in SFO: {}", x);
92    ///}
93    pub fn get_tz(&self, code: &str) -> Option<Tz> {
94        match self.get_tz_name(code) {
95            Some(t) => {
96                let tz: Tz = t.parse().expect("Failed to parse timezone.");
97                Some(tz)
98            }
99            None => None,
100        }
101    }
102}