use chrono::DateTime;
use chrono::Utc;
use serde::de::Deserializer;
use serde::de::Error;
use serde::de::Unexpected;
use serde::Deserialize;
use crate::Str;
fn datetime_from_str<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let time = String::deserialize(deserializer)?;
DateTime::parse_from_rfc3339(&time)
.map(|datetime| datetime.with_timezone(&Utc))
.map_err(|_| Error::invalid_value(Unexpected::Str(&time), &"a date time string"))
}
#[derive(Copy, Clone, Debug, Deserialize, PartialEq)]
pub enum Status {
#[serde(rename = "open")]
Open,
#[serde(rename = "closed")]
Closed,
#[serde(other)]
Unknown,
}
#[derive(Copy, Clone, Debug, Deserialize, PartialEq)]
pub struct Market {
#[serde(rename = "market")]
pub status: Status,
#[serde(rename = "serverTime", deserialize_with = "datetime_from_str")]
pub server_time: DateTime<Utc>,
}
Endpoint! {
pub Get(()),
Ok => Market, [
OK,
],
Err => GetError, []
fn path(_input: &Self::Input) -> Str {
"/v1/marketstatus/now".into()
}
}
#[cfg(not(target_arch = "wasm32"))]
#[cfg(test)]
mod tests {
use super::*;
use chrono::naive::NaiveTime;
use test_log::test;
use crate::Client;
#[test(tokio::test)]
async fn request_market_status() {
let client = Client::from_env().unwrap();
let market = client.issue::<Get>(()).await.unwrap();
let market_time = market.server_time.naive_local().time();
let open = NaiveTime::from_hms(9, 30, 0);
let close = NaiveTime::from_hms(16, 00, 0);
if market.status == Status::Open {
assert!(market_time >= open);
assert!(market_time < close);
}
}
}