bom_buddy/
location.rs

1use crate::station::WeatherStation;
2use crate::weather::Weather;
3use serde::{Deserialize, Serialize};
4use std::fmt::{self, Display};
5use strum_macros::{Display, EnumString};
6
7#[derive(Debug, Deserialize, Serialize)]
8pub struct Location {
9    pub geohash: String,
10    pub station: Option<WeatherStation>,
11    pub has_wave: bool,
12    pub id: String,
13    pub latitude: f64,
14    pub longitude: f64,
15    pub marine_area_id: Option<String>,
16    pub name: String,
17    pub state: State,
18    pub postcode: String,
19    pub tidal_point: Option<String>,
20    pub timezone: String,
21    pub weather: Weather,
22}
23
24impl Display for Location {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        write!(f, "{} {} {}", self.name, self.state, self.postcode)
27    }
28}
29
30#[derive(Debug, Deserialize, Serialize)]
31pub struct LocationData {
32    pub geohash: String,
33    pub has_wave: bool,
34    pub id: String,
35    pub latitude: f64,
36    pub longitude: f64,
37    pub marine_area_id: Option<String>,
38    pub name: String,
39    // The locations API endpoint sometimes returns a state with the value 'OT' (Other??)
40    // The SearchResult seems to have a valid state in these cases, so keep this as a String and
41    // use the SearchResult's State enum in the create_location function
42    pub state: String,
43    pub tidal_point: Option<String>,
44    pub timezone: String,
45}
46
47#[derive(Serialize, Deserialize)]
48pub struct LocationMetadata {
49    pub copyright: String,
50    pub response_timestamp: String,
51}
52
53#[derive(Serialize, Deserialize)]
54pub struct LocationResponse {
55    pub data: LocationData,
56    pub metadata: LocationMetadata,
57}
58
59#[derive(Clone, Debug, Serialize, Deserialize)]
60pub struct SearchResult {
61    pub geohash: String,
62    pub id: String,
63    pub name: String,
64    pub postcode: String,
65    pub state: State,
66}
67
68impl fmt::Display for SearchResult {
69    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70        write!(f, "{} {} {}", self.name, self.state, self.postcode)
71    }
72}
73
74#[derive(Serialize, Deserialize)]
75pub struct SearchMetadata {
76    pub copyright: String,
77    pub response_timestamp: String,
78}
79
80#[derive(Serialize, Deserialize)]
81pub struct SearchResponse {
82    pub data: Vec<SearchResult>,
83    pub metadata: SearchMetadata,
84}
85
86#[derive(Clone, Debug, Display, Deserialize, Serialize, Eq, PartialEq, EnumString)]
87#[serde(rename_all = "UPPERCASE")]
88#[strum(serialize_all = "UPPERCASE")]
89pub enum State {
90    Act,
91    Nsw,
92    Vic,
93    Qld,
94    Tas,
95    Sa,
96    Nt,
97    Wa,
98}
99
100impl State {
101    pub fn get_product_code(&self, id: &str) -> String {
102        let prefix = match self {
103            State::Nt => "IDD",
104            State::Nsw => "IDN",
105            State::Act => "IDN",
106            State::Qld => "IDQ",
107            State::Sa => "IDS",
108            State::Tas => "IDT",
109            State::Vic => "IDV",
110            State::Wa => "IDW",
111        };
112
113        format!("{prefix}{id}")
114    }
115}