55 lines
1.3 KiB
Rust
55 lines
1.3 KiB
Rust
use crate::models::Response;
|
|
use crate::models::route::{RouteRequest, RouteResp};
|
|
use reqwest::{Client, Url};
|
|
use thiserror::Error;
|
|
|
|
pub mod models;
|
|
|
|
const CTA_API_URL: &str = "http://lapi.transitchicago.com/api/1.0/";
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum Error {
|
|
#[error("Failed to deserialize response from API: {0}")]
|
|
JsonParseFailure(#[from] serde_json::Error),
|
|
#[error("Reqwest failure: {0}")]
|
|
ReqwestFailure(#[from] reqwest::Error),
|
|
#[error("URL parse failure: {0}")]
|
|
UrlParseError(#[from] url::ParseError),
|
|
}
|
|
|
|
pub struct CTAClient {
|
|
key: String,
|
|
client: Client,
|
|
url: Url,
|
|
}
|
|
|
|
impl CTAClient {
|
|
pub fn new(key: String) -> Self {
|
|
Self {
|
|
key,
|
|
client: Default::default(),
|
|
url: Url::parse(CTA_API_URL).unwrap(),
|
|
}
|
|
}
|
|
|
|
pub async fn fetch_route(&mut self, route: &str) -> Result<RouteResp, Error> {
|
|
let req = RouteRequest {
|
|
rt: route.to_string(),
|
|
key: self.key.clone(),
|
|
};
|
|
|
|
let url = self.url.join("ttpositions.aspx")?;
|
|
let resp: Response<RouteResp> = self
|
|
.client
|
|
.get(url)
|
|
.query(&req)
|
|
.query(&[("outputType", "JSON")])
|
|
.send()
|
|
.await?
|
|
.json()
|
|
.await?;
|
|
|
|
Ok(resp.ctatt)
|
|
}
|
|
}
|