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 { let req = RouteRequest { rt: route.to_string(), key: self.key.clone(), }; let url = self.url.join("ttpositions.aspx")?; let resp: Response = self .client .get(url) .query(&req) .query(&[("outputType", "JSON")]) .send() .await? .json() .await?; Ok(resp.ctatt) } }