use serde::de::DeserializeOwned;
use crate::{
allowance::{AllowanceCheck, AllowanceCheckURL},
area_info::{AreaInfo, AreaInfoURLBuilder},
area_nearby::{AreaNearby, AreasNearbyURLBuilder},
area_search::{AreaSearch, AreaSearchURLBuilder},
errors::{APIError, HttpError},
get_token_from_env,
status::{EskomStatus, EskomStatusUrl},
topics_nearby::{TopicsNearby, TopicsNearbyUrlBuilder},
Endpoint,
};
pub struct UreqClient {
token: String,
}
impl UreqClient {
pub fn new(token: String) -> Self {
UreqClient { token }
}
pub fn new_with_env(var_name: Option<&str>) -> Self {
match get_token_from_env(var_name) {
Ok(val) => UreqClient { token: val },
Err(e) => panic!("Error: {}", e),
}
}
pub fn get_load_shedding_status(&self) -> Result<EskomStatus, HttpError> {
let c = EskomStatusUrl::default();
c.ureq(&self.token)
}
pub fn get_area_info(&self, area_id: &str) -> Result<AreaInfo, HttpError> {
let t = AreaInfoURLBuilder::default()
.area_id(area_id.to_owned())
.build()
.map_err(|_| HttpError::AreaIdNotSet)?;
t.ureq(&self.token)
}
pub fn areas_nearby(&self, lat: f32, long: f32) -> Result<AreaNearby, HttpError> {
let t = AreasNearbyURLBuilder::default()
.latitude(lat)
.longitude(long)
.build()
.map_err(|_| HttpError::LongitudeOrLatitudeNotSet {
longitude: lat,
latitude: long,
})?;
t.ureq(&self.token)
}
pub fn areas_search(&self, search_term: &str) -> Result<AreaSearch, HttpError> {
let t = AreaSearchURLBuilder::default()
.search_term(search_term)
.build()
.map_err(|_| HttpError::SearchTextNotSet)?;
t.ureq(&self.token)
}
pub fn topics_nearby(&self, lat: f32, long: f32) -> Result<TopicsNearby, HttpError> {
let t = TopicsNearbyUrlBuilder::default()
.latitude(lat)
.longitude(long)
.build()
.map_err(|_| HttpError::LongitudeOrLatitudeNotSet {
longitude: lat,
latitude: long,
})?;
t.ureq(&self.token)
}
pub fn check_allowance(&self) -> Result<AllowanceCheck, HttpError> {
let t = AllowanceCheckURL::default();
t.ureq(&self.token)
}
}
pub fn handle_ureq_response<T: DeserializeOwned>(
response: Result<ureq::Response, ureq::Error>,
) -> Result<T, HttpError> {
match response {
Ok(resp) => resp
.into_json::<T>()
.map_err(|e| HttpError::UnknownError(e.to_string())),
Err(ureq::Error::Status(code, response)) => match code {
400 => Err(HttpError::APIError(APIError::BadRequest)),
403 => Err(HttpError::APIError(APIError::Forbidden)),
404 => Err(HttpError::APIError(APIError::NotFound)),
429 => Err(HttpError::APIError(APIError::TooManyRequests)),
500..=509 => Err(HttpError::APIError(APIError::ServerError(
response.into_string().unwrap(),
))),
_a => Err(HttpError::Unknown),
},
Err(_) => Err(HttpError::NoInternet),
}
}