add response structs
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use anyhow::Result;
|
||||
use chrono::{DateTime, Local, TimeZone, Utc};
|
||||
use serde::{de, Deserialize, Deserializer};
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct Departure {
|
||||
id: String,
|
||||
dl_id: String,
|
||||
line_name: String,
|
||||
direction: String,
|
||||
platform: Platform,
|
||||
mot: String,
|
||||
#[serde(default, deserialize_with = "deserialize_realtime")]
|
||||
real_time: Option<DateTime<Local>>,
|
||||
#[serde(deserialize_with = "deserialize_timestamp")]
|
||||
scheduled_time: DateTime<Local>,
|
||||
state: Option<String>,
|
||||
route_changes: Vec<RouteChange>,
|
||||
diva: Diva,
|
||||
cancel_reasons: Vec<CancelReason>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct Platform {
|
||||
name: String,
|
||||
#[serde(rename = "Type")]
|
||||
type_: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct RouteChange {
|
||||
// fields omitted
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct Diva {
|
||||
number: String,
|
||||
network: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct CancelReason {
|
||||
// fields omitted
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct Response {
|
||||
name: String,
|
||||
status: Status,
|
||||
place: String,
|
||||
expiration_time: String,
|
||||
departures: Vec<Departure>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct Status {
|
||||
code: String,
|
||||
}
|
||||
|
||||
/// Deserialize a timestamp in the form of '/Date(1671713820000-0000)/'
|
||||
fn deserialize_timestamp<'de, D>(deserializer: D) -> Result<DateTime<Local>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
let timestamp: i64 = s
|
||||
.trim_start_matches("/Date(")
|
||||
.trim_end_matches(")/")
|
||||
.split('-')
|
||||
.next()
|
||||
.ok_or_else(|| de::Error::custom("Invalid timestamp format"))?
|
||||
.parse()
|
||||
.map_err(de::Error::custom)?;
|
||||
let result = Utc.timestamp_millis_opt(timestamp).unwrap();
|
||||
|
||||
let local_tz = chrono::offset::Local::now().timezone();
|
||||
Ok(result.with_timezone(&local_tz))
|
||||
}
|
||||
|
||||
fn deserialize_realtime<'de, D>(deserializer: D) -> Result<Option<DateTime<Local>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
match deserialize_timestamp(deserializer) {
|
||||
Ok(inner) => Ok(Some(inner)),
|
||||
Err(_) => Ok(None),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user