From f21b94c007517f8a0e234a81654ecb7e9643ee7e Mon Sep 17 00:00:00 2001 From: Rob Fitzgerald Date: Mon, 29 Jun 2026 08:41:05 -0600 Subject: [PATCH 01/43] begin gbfs integration --- rust/Cargo.toml | 1 + rust/bambam-gbfs/Cargo.toml | 1 + rust/bambam-gbfs/src/app/download/run.rs | 20 ++++++++++++++++++-- rust/bambam-gbfs/src/app/gbfs_cli.rs | 15 +++++++++------ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e7113a6a..59fbbb95 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -36,6 +36,7 @@ downloader = { version = "0.2.8" } env_logger = "0.11.8" flate2 = "1.0" futures = { version = "0.3.31", features = ["executor"] } +gbfs_types = "0.1.4" geo = { version = "0.33.1", features = ["use-serde"] } geo-buffer = "0.2.0" geo-traits = "0.3.0" diff --git a/rust/bambam-gbfs/Cargo.toml b/rust/bambam-gbfs/Cargo.toml index 09039bd1..8c32500c 100644 --- a/rust/bambam-gbfs/Cargo.toml +++ b/rust/bambam-gbfs/Cargo.toml @@ -9,6 +9,7 @@ description = "GBFS Extensions for The Behavior and Advanced Mobility Big Access chrono = { workspace = true } clap = { workspace = true } env_logger = { workspace = true } +gbfs_types = { workspace = true } geo = { workspace = true } humantime = { workspace = true } kdam = { workspace = true } diff --git a/rust/bambam-gbfs/src/app/download/run.rs b/rust/bambam-gbfs/src/app/download/run.rs index 8f569e00..ececdd61 100644 --- a/rust/bambam-gbfs/src/app/download/run.rs +++ b/rust/bambam-gbfs/src/app/download/run.rs @@ -6,16 +6,32 @@ use chrono::TimeDelta; /// to files to be consumed by BAMBAM. /// /// # Arguments -/// * url - URL to the GBFS dataset +/// * url - URL to the GBFS dataset's system-information file /// * out_dir - output directory to write the processed GBFS data /// * dur - how long to poll the GBFS API /// /// # Result /// If successful, returns nothing, otherwise an error -pub fn run_gbfs_download(url: &str, out_dir: &Path, dur: &TimeDelta) -> Result<(), String> { +pub async fn run_gbfs_download(url: &str, out_dir: &Path, dur: &TimeDelta) -> Result<(), String> { let dur_secs = dur.as_seconds_f64(); log::debug!( "run_gbfs_download with url={url}, out_dir={out_dir:?}, duration (seconds)={dur_secs}" ); + let client = reqwest::Client::new(); + let response = client + .get(url) + .header("User-Agent", "rust-reqwest") + .send() + .await?; + + if response.status().is_success() { + let system_information: SystemInformationFile = response.json().await?; + println!("systemInformation version: {}", system_information.version); + println!( + "systemInformation data: {}", + system_information.data.system_id + ); + } + todo!("download + post-processing logic") } diff --git a/rust/bambam-gbfs/src/app/gbfs_cli.rs b/rust/bambam-gbfs/src/app/gbfs_cli.rs index 1cf0a2e2..9be3f445 100644 --- a/rust/bambam-gbfs/src/app/gbfs_cli.rs +++ b/rust/bambam-gbfs/src/app/gbfs_cli.rs @@ -33,17 +33,20 @@ pub enum GbfsOperation { } impl GbfsOperation { - pub fn run(&self) -> Result<(), String> { + pub async fn run(&self) -> Result<(), String> { match self { GbfsOperation::Download { gbfs_url, output_directory, collect_duration, - } => crate::app::download::run_gbfs_download( - gbfs_url, - Path::new(output_directory), - collect_duration, - ), + } => { + crate::app::download::run_gbfs_download( + gbfs_url, + Path::new(output_directory), + collect_duration, + ) + .await + } } } } From f72e037f9a41326fd41f3b15b9e531ae129f0fda Mon Sep 17 00:00:00 2001 From: Rob Fitzgerald Date: Wed, 15 Jul 2026 13:24:28 -0600 Subject: [PATCH 02/43] resolve gbfs_types import + ignore pyo3 feature --- rust/Cargo.toml | 3 ++- rust/bambam-gbfs/Cargo.toml | 1 + rust/bambam-py/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5023e364..b322d6e0 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -36,7 +36,7 @@ downloader = { version = "0.2.8" } env_logger = "0.11.8" flate2 = "1.0" futures = { version = "0.3.31", features = ["executor"] } -gbfs_types = "0.1.4" +gbfs_types = { version = "0.1.4", default-features = false, features = ["reqwest_blocking"]} geo = { version = "0.33.1", features = ["use-serde"] } geo-buffer = "0.2.0" geo-traits = "0.3.0" @@ -59,6 +59,7 @@ ordered-float = { version = "5.1.0", features = ["serde"] } osmio = "0.14.0" osmpbf = "0.3.4" parquet = { version = "=58.0.0", features = ["snap", "async", "object_store"] } +pyo3 = { version = "0.29.0", features = ["extension-module", "serde"] } rand = "0.10.0" rayon = "1.10.0" regex = { version = "1.11.1" } diff --git a/rust/bambam-gbfs/Cargo.toml b/rust/bambam-gbfs/Cargo.toml index 8c32500c..b794f3bd 100644 --- a/rust/bambam-gbfs/Cargo.toml +++ b/rust/bambam-gbfs/Cargo.toml @@ -19,3 +19,4 @@ routee-compass-core = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } serde_with = { workspace = true } +tokio = { workspace = true } \ No newline at end of file diff --git a/rust/bambam-py/Cargo.toml b/rust/bambam-py/Cargo.toml index d849f589..6d00bd4e 100644 --- a/rust/bambam-py/Cargo.toml +++ b/rust/bambam-py/Cargo.toml @@ -14,7 +14,7 @@ inventory = { workspace = true } itertools = { workspace = true } -pyo3 = { version = "0.29.0", features = ["extension-module", "serde"] } +pyo3 = { workspace = true } routee-compass = { workspace = true, default-features = false } routee-compass-core = { workspace = true } routee-compass-macros = { workspace = true } From 1b0c27f7e15bd81e8d3c3adbba803cd42cefc7d8 Mon Sep 17 00:00:00 2001 From: Rob Fitzgerald Date: Wed, 15 Jul 2026 13:24:44 -0600 Subject: [PATCH 03/43] wire in tokio runtime + fix error channel --- rust/bambam-gbfs/src/app/download/run.rs | 10 +++++++--- rust/bambam-gbfs/src/main.rs | 6 ++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rust/bambam-gbfs/src/app/download/run.rs b/rust/bambam-gbfs/src/app/download/run.rs index ececdd61..1895c507 100644 --- a/rust/bambam-gbfs/src/app/download/run.rs +++ b/rust/bambam-gbfs/src/app/download/run.rs @@ -1,6 +1,7 @@ use std::path::Path; use chrono::TimeDelta; +use gbfs_types::v3_0::files::SystemInformationFile; /// downloads GBFS data for some duration. aggregates the resulting rows and writes them /// to files to be consumed by BAMBAM. @@ -22,10 +23,13 @@ pub async fn run_gbfs_download(url: &str, out_dir: &Path, dur: &TimeDelta) -> Re .get(url) .header("User-Agent", "rust-reqwest") .send() - .await?; + .await + .map_err(|e| format!("failed to connect to GBFS URL: {e}"))?; if response.status().is_success() { - let system_information: SystemInformationFile = response.json().await?; + let system_information: SystemInformationFile = response.json().await.map_err(|e| { + format!("failed to deserialize system information file from HTTP response: {e}") + })?; println!("systemInformation version: {}", system_information.version); println!( "systemInformation data: {}", @@ -33,5 +37,5 @@ pub async fn run_gbfs_download(url: &str, out_dir: &Path, dur: &TimeDelta) -> Re ); } - todo!("download + post-processing logic") + Ok(()) } diff --git a/rust/bambam-gbfs/src/main.rs b/rust/bambam-gbfs/src/main.rs index acf2772f..e163c893 100644 --- a/rust/bambam-gbfs/src/main.rs +++ b/rust/bambam-gbfs/src/main.rs @@ -1,10 +1,12 @@ use bambam_gbfs::app::GbfsCliArguments; use clap::Parser; -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let args = GbfsCliArguments::parse(); - match args.op.run() { + + match args.op.run().await { Ok(_) => log::info!("finished."), Err(e) => { log::error!("failed running bambam_gbfs: {e}"); From 50fe4d6726231e829c034400fce87438523f5422 Mon Sep 17 00:00:00 2001 From: Rob Fitzgerald Date: Wed, 15 Jul 2026 15:27:11 -0600 Subject: [PATCH 04/43] CLI GBFS app retrieves geofence + system info from GBFS URL --- .../src/app/download/entry_point.rs | 22 ++++++ .../src/app/download/gbfs_version.rs | 37 ++++++++++ rust/bambam-gbfs/src/app/download/mod.rs | 6 ++ rust/bambam-gbfs/src/app/download/ops.rs | 27 ++++++++ rust/bambam-gbfs/src/app/download/run.rs | 37 +++++----- rust/bambam-gbfs/src/app/download/v3_ops.rs | 67 +++++++++++++++++++ rust/bambam-gbfs/src/app/gbfs_cli.rs | 20 +++++- 7 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 rust/bambam-gbfs/src/app/download/entry_point.rs create mode 100644 rust/bambam-gbfs/src/app/download/gbfs_version.rs create mode 100644 rust/bambam-gbfs/src/app/download/ops.rs create mode 100644 rust/bambam-gbfs/src/app/download/v3_ops.rs diff --git a/rust/bambam-gbfs/src/app/download/entry_point.rs b/rust/bambam-gbfs/src/app/download/entry_point.rs new file mode 100644 index 00000000..c762e788 --- /dev/null +++ b/rust/bambam-gbfs/src/app/download/entry_point.rs @@ -0,0 +1,22 @@ +use clap::ValueEnum; +use serde::{Deserialize, Serialize}; + +/// target of an initial HTTP call to a GBFS archive. +/// for an explanation, see . +#[derive(Serialize, Deserialize, Debug, Clone, Copy, ValueEnum, PartialEq, Eq, Hash)] +#[serde(rename_all = "snake_case")] +pub enum EntryPoint { + /// manifest.json file + Manifest, + /// gbfs.json file for a specific GBFS version. + Gbfs, +} + +impl std::fmt::Display for EntryPoint { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EntryPoint::Manifest => write!(f, "manifest"), + EntryPoint::Gbfs => write!(f, "gbfs"), + } + } +} diff --git a/rust/bambam-gbfs/src/app/download/gbfs_version.rs b/rust/bambam-gbfs/src/app/download/gbfs_version.rs new file mode 100644 index 00000000..5957ef27 --- /dev/null +++ b/rust/bambam-gbfs/src/app/download/gbfs_version.rs @@ -0,0 +1,37 @@ +use std::str::FromStr; + +use clap::ValueEnum; +use serde::{Deserialize, Serialize}; + +/// GBFS version of the targeted archive. only supported versions are included. +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum GbfsVersion { + #[serde(rename = "v3.0")] + V3_0, +} + +impl GbfsVersion { + pub const ALL: [&'static str; 1] = ["v3.0"]; +} + +impl std::fmt::Display for GbfsVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GbfsVersion::V3_0 => write!(f, "v3.0"), + } + } +} + +impl FromStr for GbfsVersion { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "v3.0" => Ok(Self::V3_0), + _ => Err(format!( + "unknown version '{s}', must be one of [{}]", + Self::ALL.join(", ") + )), + } + } +} diff --git a/rust/bambam-gbfs/src/app/download/mod.rs b/rust/bambam-gbfs/src/app/download/mod.rs index ffd60131..4e3a9977 100644 --- a/rust/bambam-gbfs/src/app/download/mod.rs +++ b/rust/bambam-gbfs/src/app/download/mod.rs @@ -1,3 +1,9 @@ +mod entry_point; +mod gbfs_version; mod run; pub use run::run_gbfs_download; +pub mod ops; +pub use entry_point::EntryPoint; +pub use gbfs_version::GbfsVersion; +pub mod v3_ops; diff --git a/rust/bambam-gbfs/src/app/download/ops.rs b/rust/bambam-gbfs/src/app/download/ops.rs new file mode 100644 index 00000000..f26b76db --- /dev/null +++ b/rust/bambam-gbfs/src/app/download/ops.rs @@ -0,0 +1,27 @@ +use reqwest::{Client, IntoUrl}; +use serde::de::DeserializeOwned; + +use crate::app::download::{EntryPoint, GbfsVersion}; + +/// helper function for running a client HTTP GET call to retrieve a JSON object. +pub async fn retrieve_file<'a, 'b, T: DeserializeOwned, U: IntoUrl>( + client: &'b Client, + url: U, +) -> Result { + let response = client + .get(url) + .header("User-Agent", "rust-reqwest") + .send() + .await + .map_err(|e| format!("failed to connect to GBFS URL: {e}"))?; + let status = response.status(); + if status.is_success() { + let t: T = response.json().await.map_err(|e| { + let type_name = std::any::type_name::(); + format!("failed to deserialize {type_name} file from HTTP response: {e}") + })?; + Ok(t) + } else { + Err(format!("client response is {status}")) + } +} diff --git a/rust/bambam-gbfs/src/app/download/run.rs b/rust/bambam-gbfs/src/app/download/run.rs index 1895c507..5e966bf5 100644 --- a/rust/bambam-gbfs/src/app/download/run.rs +++ b/rust/bambam-gbfs/src/app/download/run.rs @@ -1,7 +1,8 @@ use std::path::Path; use chrono::TimeDelta; -use gbfs_types::v3_0::files::SystemInformationFile; + +use crate::app::download::{EntryPoint, GbfsVersion, v3_ops}; /// downloads GBFS data for some duration. aggregates the resulting rows and writes them /// to files to be consumed by BAMBAM. @@ -13,28 +14,30 @@ use gbfs_types::v3_0::files::SystemInformationFile; /// /// # Result /// If successful, returns nothing, otherwise an error -pub async fn run_gbfs_download(url: &str, out_dir: &Path, dur: &TimeDelta) -> Result<(), String> { +pub async fn run_gbfs_download( + url: &str, + out_dir: &Path, + dur: &TimeDelta, + entry_point: EntryPoint, + version: GbfsVersion, +) -> Result<(), String> { let dur_secs = dur.as_seconds_f64(); log::debug!( "run_gbfs_download with url={url}, out_dir={out_dir:?}, duration (seconds)={dur_secs}" ); let client = reqwest::Client::new(); - let response = client - .get(url) - .header("User-Agent", "rust-reqwest") - .send() - .await - .map_err(|e| format!("failed to connect to GBFS URL: {e}"))?; - if response.status().is_success() { - let system_information: SystemInformationFile = response.json().await.map_err(|e| { - format!("failed to deserialize system information file from HTTP response: {e}") - })?; - println!("systemInformation version: {}", system_information.version); - println!( - "systemInformation data: {}", - system_information.data.system_id - ); + let result = match (version, entry_point) { + (GbfsVersion::V3_0, EntryPoint::Manifest) => { + v3_ops::run_v3_0_manifest(&client, url).await? + } + (GbfsVersion::V3_0, EntryPoint::Gbfs) => { + v3_ops::run_v3_0_gbfs(&client, url).await.map(|g| vec![g])? + } + }; + + for row in result.into_iter() { + println!("{}", serde_json::to_string_pretty(&row).unwrap_or_default()); } Ok(()) diff --git a/rust/bambam-gbfs/src/app/download/v3_ops.rs b/rust/bambam-gbfs/src/app/download/v3_ops.rs new file mode 100644 index 00000000..9c039d0f --- /dev/null +++ b/rust/bambam-gbfs/src/app/download/v3_ops.rs @@ -0,0 +1,67 @@ +use gbfs_types::v3_0::files::{GbfsFile, GeofencingZonesFile, SystemInformationFile}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GbfsV3Import { + /// contains the system-level metadata including opening hours. + pub info: SystemInformationFile, + /// contains the zonal geometries, global, and zone-specific traversal rules for this system. + pub geofence: GeofencingZonesFile, +} + +/// runs retrieval from a manifest file. allows mutli-system downloads. +pub async fn run_v3_0_manifest( + client: &reqwest::Client, + url: &str, +) -> Result, String> { + let manifest: gbfs_types::v3_0::files::ManifestFile = + super::ops::retrieve_file(&client, url).await?; + + // find v3 datasets for each system in this manifest and run the inner retrieval function + let mut results = vec![]; + for system in manifest.data.datasets.iter() { + let system_id = system.system_id.clone(); + let v_search = system.versions.iter().find(|v| v.version == "3.0"); + match v_search { + Some(v3) => { + let gbfs_url = v3.url.value.clone(); + let result = run_v3_0_gbfs(client, &gbfs_url).await?; + results.push(result); + } + None => return Err(format!("in system {system_id} no v3.0 was found.")), + } + } + + Ok(results) +} + +/// runs retrieval at the gbfs.json level, retrieving from a single system. +pub async fn run_v3_0_gbfs(client: &reqwest::Client, url: &str) -> Result { + let gbfs: GbfsFile = super::ops::retrieve_file(&client, url).await?; + + let geofencing_zones_url = gbfs + .data + .get_geofencing_zones_url() + .ok_or_else(|| format!("feed at {url} does not include geofencing_zones"))?; + let geofence: GeofencingZonesFile = + super::ops::retrieve_file(&client, &geofencing_zones_url.value) + .await + .map_err(|e| { + format!( + "while attempting HTTP GET '{}': {e}", + geofencing_zones_url.value + ) + })?; + + let system_info_url = gbfs + .data + .get_system_information_url() + .ok_or_else(|| format!("feed at {url} does not include geofencing_zones"))?; + let info: SystemInformationFile = super::ops::retrieve_file(&client, &system_info_url.value) + .await + .map_err(|e| format!("while attempting HTTP GET '{}': {e}", system_info_url.value))?; + + let result = GbfsV3Import { info, geofence }; + + Ok(result) +} diff --git a/rust/bambam-gbfs/src/app/gbfs_cli.rs b/rust/bambam-gbfs/src/app/gbfs_cli.rs index 9be3f445..c36ac7d8 100644 --- a/rust/bambam-gbfs/src/app/gbfs_cli.rs +++ b/rust/bambam-gbfs/src/app/gbfs_cli.rs @@ -1,9 +1,11 @@ -use std::path::Path; +use std::{path::Path, str::FromStr}; use chrono::TimeDelta; use clap::{Parser, Subcommand}; use serde::{Deserialize, Serialize}; +use crate::app::download::{EntryPoint, GbfsVersion}; + /// command line tool providing GBFS processing scripts #[derive(Parser)] #[command(author, version, about, long_about = None)] @@ -26,9 +28,15 @@ pub enum GbfsOperation { #[arg(short, long, default_value_t = String::from("."))] output_directory: String, /// duration to collect data rows. provide in human-readable time values - /// 2m, 30s, 2h, 2days... + /// 2m, 30s, 2h, 2days... applies to wait time modeling capability. #[arg(short, long, value_parser = parse_duration, default_value = "10m")] collect_duration: TimeDelta, + /// target of the initial HTTP call. + #[arg(long, default_value_t = EntryPoint::Gbfs)] + entry_point: EntryPoint, + /// GBFS version number to download. + #[arg(long, default_value_t = GbfsVersion::V3_0, value_parser = parse_version)] + version: GbfsVersion, }, } @@ -39,11 +47,15 @@ impl GbfsOperation { gbfs_url, output_directory, collect_duration, + entry_point, + version, } => { crate::app::download::run_gbfs_download( gbfs_url, Path::new(output_directory), collect_duration, + *entry_point, + *version, ) .await } @@ -56,3 +68,7 @@ fn parse_duration(s: &str) -> Result { humantime::parse_duration(s).map_err(|e| format!("Invalid duration: {e}"))?; chrono::TimeDelta::from_std(std_duration).map_err(|e| format!("TimeDelta out of range: {e}")) } + +fn parse_version(s: &str) -> Result { + GbfsVersion::from_str(s) +} From 059ac76c87e4dcb20da3ec86006bebd6d15133cf Mon Sep 17 00:00:00 2001 From: Rob Fitzgerald Date: Wed, 15 Jul 2026 15:29:37 -0600 Subject: [PATCH 05/43] cargo sort --- rust/Cargo.toml | 2 +- rust/bambam-gbfs/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b322d6e0..1995de92 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -36,7 +36,7 @@ downloader = { version = "0.2.8" } env_logger = "0.11.8" flate2 = "1.0" futures = { version = "0.3.31", features = ["executor"] } -gbfs_types = { version = "0.1.4", default-features = false, features = ["reqwest_blocking"]} +gbfs_types = { version = "0.1.4", default-features = false, features = ["reqwest_blocking"] } geo = { version = "0.33.1", features = ["use-serde"] } geo-buffer = "0.2.0" geo-traits = "0.3.0" diff --git a/rust/bambam-gbfs/Cargo.toml b/rust/bambam-gbfs/Cargo.toml index b794f3bd..f4f7fd1e 100644 --- a/rust/bambam-gbfs/Cargo.toml +++ b/rust/bambam-gbfs/Cargo.toml @@ -19,4 +19,4 @@ routee-compass-core = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } serde_with = { workspace = true } -tokio = { workspace = true } \ No newline at end of file +tokio = { workspace = true } From 40d90a7b1823476ebe9733efc24fcdc6e260a01a Mon Sep 17 00:00:00 2001 From: Rob Fitzgerald Date: Wed, 15 Jul 2026 15:29:47 -0600 Subject: [PATCH 06/43] clippy --- rust/bambam-gbfs/src/app/download/gbfs_version.rs | 1 - rust/bambam-gbfs/src/app/download/ops.rs | 1 - rust/bambam-gbfs/src/app/download/v3_ops.rs | 8 ++++---- rust/bambam-osm/src/app/network/wci/bulk_compute_wci.rs | 2 +- rust/bambam-osm/src/model/osm/graph/compass_writer.rs | 2 +- .../src/model/traversal/time_delay/time_delay_record.rs | 6 +++--- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/rust/bambam-gbfs/src/app/download/gbfs_version.rs b/rust/bambam-gbfs/src/app/download/gbfs_version.rs index 5957ef27..8a93b2a3 100644 --- a/rust/bambam-gbfs/src/app/download/gbfs_version.rs +++ b/rust/bambam-gbfs/src/app/download/gbfs_version.rs @@ -1,6 +1,5 @@ use std::str::FromStr; -use clap::ValueEnum; use serde::{Deserialize, Serialize}; /// GBFS version of the targeted archive. only supported versions are included. diff --git a/rust/bambam-gbfs/src/app/download/ops.rs b/rust/bambam-gbfs/src/app/download/ops.rs index f26b76db..07e247e9 100644 --- a/rust/bambam-gbfs/src/app/download/ops.rs +++ b/rust/bambam-gbfs/src/app/download/ops.rs @@ -1,7 +1,6 @@ use reqwest::{Client, IntoUrl}; use serde::de::DeserializeOwned; -use crate::app::download::{EntryPoint, GbfsVersion}; /// helper function for running a client HTTP GET call to retrieve a JSON object. pub async fn retrieve_file<'a, 'b, T: DeserializeOwned, U: IntoUrl>( diff --git a/rust/bambam-gbfs/src/app/download/v3_ops.rs b/rust/bambam-gbfs/src/app/download/v3_ops.rs index 9c039d0f..9e2c5681 100644 --- a/rust/bambam-gbfs/src/app/download/v3_ops.rs +++ b/rust/bambam-gbfs/src/app/download/v3_ops.rs @@ -15,7 +15,7 @@ pub async fn run_v3_0_manifest( url: &str, ) -> Result, String> { let manifest: gbfs_types::v3_0::files::ManifestFile = - super::ops::retrieve_file(&client, url).await?; + super::ops::retrieve_file(client, url).await?; // find v3 datasets for each system in this manifest and run the inner retrieval function let mut results = vec![]; @@ -37,14 +37,14 @@ pub async fn run_v3_0_manifest( /// runs retrieval at the gbfs.json level, retrieving from a single system. pub async fn run_v3_0_gbfs(client: &reqwest::Client, url: &str) -> Result { - let gbfs: GbfsFile = super::ops::retrieve_file(&client, url).await?; + let gbfs: GbfsFile = super::ops::retrieve_file(client, url).await?; let geofencing_zones_url = gbfs .data .get_geofencing_zones_url() .ok_or_else(|| format!("feed at {url} does not include geofencing_zones"))?; let geofence: GeofencingZonesFile = - super::ops::retrieve_file(&client, &geofencing_zones_url.value) + super::ops::retrieve_file(client, &geofencing_zones_url.value) .await .map_err(|e| { format!( @@ -57,7 +57,7 @@ pub async fn run_v3_0_gbfs(client: &reqwest::Client, url: &str) -> Result> = Arc::new(Mutex::new( BarBuilder::default() - .desc(format!("Computing WCI scores for the road network")) + .desc("Computing WCI scores for the road network".to_string()) .total(way_rtree_entries.len()) .build()?, )); diff --git a/rust/bambam-osm/src/model/osm/graph/compass_writer.rs b/rust/bambam-osm/src/model/osm/graph/compass_writer.rs index 994114ff..e10566cb 100644 --- a/rust/bambam-osm/src/model/osm/graph/compass_writer.rs +++ b/rust/bambam-osm/src/model/osm/graph/compass_writer.rs @@ -39,7 +39,7 @@ impl CompassWriter for OsmGraphVectorized { let dirname = output_directory.as_os_str().to_string_lossy(); return Err(OsmError::InternalError(format!( "unable to create directory {}", - &dirname + dirname ))); } diff --git a/rust/bambam/src/model/traversal/time_delay/time_delay_record.rs b/rust/bambam/src/model/traversal/time_delay/time_delay_record.rs index edc7adef..2023dac0 100644 --- a/rust/bambam/src/model/traversal/time_delay/time_delay_record.rs +++ b/rust/bambam/src/model/traversal/time_delay/time_delay_record.rs @@ -59,7 +59,7 @@ impl<'de> de::Deserialize<'de> for TimeDelayRecord { .map_err(|e| { de::Error::custom(format!( "unable to parse WKT geometry '{}': {}", - &value, e + value, e )) })?; let row_geometry: Geometry = match geo_f64 { @@ -78,7 +78,7 @@ impl<'de> de::Deserialize<'de> for TimeDelayRecord { _ => { return Err(de::Error::custom(format!( "expected Polygon or MultiPolygon geometry, found unexpected type in '{}'", - &value + value ))); } }; @@ -89,7 +89,7 @@ impl<'de> de::Deserialize<'de> for TimeDelayRecord { serde_json::from_str::