58 lines
1.5 KiB
Rust
58 lines
1.5 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use tracing::warn;
|
|
|
|
#[derive(Serialize)]
|
|
struct TravelTimeRequest {
|
|
origins: Vec<[f64; 2]>,
|
|
destination: [f64; 2],
|
|
mode: String,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct TravelTimeResponse {
|
|
travel_times: Vec<Option<f64>>,
|
|
}
|
|
|
|
/// Call the R5 service to compute many-to-one travel times.
|
|
///
|
|
/// Returns a Vec of travel times in minutes (one per origin), with None for unreachable origins.
|
|
pub async fn fetch_travel_times(
|
|
client: &reqwest::Client,
|
|
r5_url: &str,
|
|
origins: Vec<[f64; 2]>,
|
|
destination: [f64; 2],
|
|
mode: &str,
|
|
) -> Result<Vec<Option<f64>>, String> {
|
|
let url = format!("{}/travel-times", r5_url);
|
|
|
|
let request_body = TravelTimeRequest {
|
|
origins,
|
|
destination,
|
|
mode: mode.to_string(),
|
|
};
|
|
|
|
let resp = client
|
|
.post(&url)
|
|
.json(&request_body)
|
|
.timeout(std::time::Duration::from_secs(60))
|
|
.send()
|
|
.await
|
|
.map_err(|e| {
|
|
warn!("R5 request failed: {}", e);
|
|
format!("R5 service error: {}", e)
|
|
})?;
|
|
|
|
if !resp.status().is_success() {
|
|
let status = resp.status();
|
|
let body = resp.text().await.unwrap_or_default();
|
|
warn!("R5 returned {}: {}", status, body);
|
|
return Err(format!("R5 service returned {}: {}", status, body));
|
|
}
|
|
|
|
let body: TravelTimeResponse = resp.json().await.map_err(|e| {
|
|
warn!("Failed to parse R5 response: {}", e);
|
|
format!("Failed to parse R5 response: {}", e)
|
|
})?;
|
|
|
|
Ok(body.travel_times)
|
|
}
|