eskom_se_push_api/
status.rs

1use std::collections::HashMap;
2
3use chrono::DateTime;
4use chrono::Utc;
5use derive_builder::Builder;
6use serde::Deserialize;
7use serde::Serialize;
8
9use crate::traits::Endpoint;
10#[cfg(any(feature = "async", doc))]
11use crate::traits::EndpointAsync;
12
13pub enum Stage {
14  NoLoadShedding,
15  Stage1,
16  Stage2,
17  Stage3,
18  Stage4,
19  Stage5,
20  Stage6,
21  Stage7,
22  Stage8,
23  /// Able to check any stage (Also future proofing). String should be a whole number.
24  /// "0" is no loadshedding. "1" is Stage 1 etc.
25  Stage(String),
26}
27
28impl PartialEq<String> for Stage {
29  fn eq(&self, other: &String) -> bool {
30    match self {
31      Stage::NoLoadShedding => "0" == other,
32      Stage::Stage1 => "1" == other,
33      Stage::Stage2 => "2" == other,
34      Stage::Stage3 => "3" == other,
35      Stage::Stage4 => "4" == other,
36      Stage::Stage5 => "5" == other,
37      Stage::Stage6 => "6" == other,
38      Stage::Stage7 => "7" == other,
39      Stage::Stage8 => "8" == other,
40      Stage::Stage(stage) => stage == other,
41    }
42  }
43}
44
45impl From<String> for Stage {
46  fn from(stage: String) -> Self {
47    match stage.as_str() {
48      "0" => Self::NoLoadShedding,
49      "1" => Self::Stage1,
50      "2" => Self::Stage2,
51      "3" => Self::Stage3,
52      "4" => Self::Stage4,
53      "5" => Self::Stage5,
54      "6" => Self::Stage6,
55      "7" => Self::Stage7,
56      "8" => Self::Stage8,
57      new_stage => Self::Stage(new_stage.to_string()),
58    }
59  }
60}
61
62#[derive(Default, Builder, Debug)]
63#[builder(setter(into))]
64pub struct EskomStatusUrl {}
65
66impl Endpoint for EskomStatusUrl {
67  type Output = EskomStatus;
68
69  fn endpoint(&self) -> std::borrow::Cow<'static, str> {
70    std::borrow::Cow::Borrowed("https://developer.sepush.co.za/business/2.0/status")
71  }
72
73  fn url(&self) -> Result<url::Url, crate::errors::HttpError> {
74    Ok(url::Url::parse(&self.endpoint()).unwrap())
75  }
76}
77
78#[cfg(any(feature = "async", doc))]
79impl EndpointAsync for EskomStatusUrl {}
80
81/// The status of load shedding nation wide and certain areas if they don't follow the
82/// nation wide status
83#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
84#[serde(rename_all = "camelCase")]
85pub struct EskomStatus {
86  pub status: HashMap<String, LoadsheddingStatus>,
87}
88
89impl EskomStatus {
90  /// Gets the nation-wide load shedding status
91  pub fn eskom(&self) -> &LoadsheddingStatus {
92    self.status.get("eskom").unwrap()
93  }
94
95  /// Gets the status for a specific area
96  /// `Note` the area needs to match the case of key
97  pub fn area(&self, area: &str) -> Option<&LoadsheddingStatus> {
98    self.status.get(area.to_lowercase().as_str())
99  }
100
101  /// Returns all the area keys
102  pub fn keys(&mut self) -> Vec<String> {
103    self.status.clone().into_keys().collect()
104  }
105}
106
107#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
108#[serde(rename_all = "camelCase")]
109pub struct LoadsheddingStatus {
110  pub name: String,
111  #[serde(rename = "next_stages")]
112  pub next_stages: Vec<NextStage>,
113  pub stage: String,
114  #[serde(rename = "stage_updated")]
115  pub stage_updated: String,
116}
117
118impl LoadsheddingStatus {
119  pub fn is_it_stage(&self, stage: Stage) -> bool {
120    stage == self.stage
121  }
122
123  pub fn get_stage(&self) -> Stage {
124    self.stage.clone().into()
125  }
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
129#[serde(rename_all = "camelCase")]
130pub struct NextStage {
131  pub stage: String,
132  #[serde(rename = "stage_start_timestamp")]
133  pub stage_start_timestamp: DateTime<Utc>,
134}
135
136impl NextStage {
137  pub fn is_it_stage(&self, stage: Stage) -> bool {
138    stage == self.stage
139  }
140
141  pub fn get_stage(&self) -> Stage {
142    self.stage.clone().into()
143  }
144}