use crate::objects::*;
use crate::Error;
use crate::GtfsReader;
use std::path::Path;
use web_time::Duration;
#[derive(Debug)]
pub struct RawGtfs {
pub read_duration: Duration,
pub calendar: Option<Result<Vec<Calendar>, Error>>,
pub calendar_dates: Option<Result<Vec<CalendarDate>, Error>>,
pub stops: Result<Vec<Stop>, Error>,
pub routes: Result<Vec<Route>, Error>,
pub trips: Result<Vec<RawTrip>, Error>,
pub agencies: Result<Vec<Agency>, Error>,
pub shapes: Option<Result<Vec<Shape>, Error>>,
pub fare_attributes: Option<Result<Vec<FareAttribute>, Error>>,
pub fare_rules: Option<Result<Vec<FareRule>, Error>>,
pub fare_products: Option<Result<Vec<FareProduct>, Error>>,
pub fare_media: Option<Result<Vec<FareMedia>, Error>>,
pub rider_categories: Option<Result<Vec<RiderCategory>, Error>>,
pub frequencies: Option<Result<Vec<RawFrequency>, Error>>,
pub transfers: Option<Result<Vec<RawTransfer>, Error>>,
pub pathways: Option<Result<Vec<RawPathway>, Error>>,
pub feed_info: Option<Result<Vec<FeedInfo>, Error>>,
pub stop_times: Result<Vec<RawStopTime>, Error>,
pub files: Vec<String>,
pub source_format: SourceFormat,
pub sha256: Option<String>,
pub translations: Option<Result<Vec<RawTranslation>, Error>>,
}
impl RawGtfs {
pub fn print_stats(&self) {
println!("GTFS data:");
println!(" Read in {:?}", self.read_duration);
println!(" Stops: {}", mandatory_file_summary(&self.stops));
println!(" Routes: {}", mandatory_file_summary(&self.routes));
println!(" Trips: {}", mandatory_file_summary(&self.trips));
println!(" Agencies: {}", mandatory_file_summary(&self.agencies));
println!(" Stop times: {}", mandatory_file_summary(&self.stop_times));
println!(" Shapes: {}", optional_file_summary(&self.shapes));
println!(" Fares: {}", optional_file_summary(&self.fare_attributes));
println!(
" Frequencies: {}",
optional_file_summary(&self.frequencies)
);
println!(" Transfers: {}", optional_file_summary(&self.transfers));
println!(" Pathways: {}", optional_file_summary(&self.pathways));
println!(" Feed info: {}", optional_file_summary(&self.feed_info));
println!(
" Translations: {}",
optional_file_summary(&self.translations)
);
}
#[cfg(not(target_arch = "wasm32"))]
pub fn new(gtfs: &str) -> Result<Self, Error> {
GtfsReader::default().raw().read(gtfs)
}
pub fn from_path<P>(path: P) -> Result<Self, Error>
where
P: AsRef<Path>,
{
GtfsReader::default().raw().read_from_path(path)
}
#[cfg(all(feature = "read-url", not(target_arch = "wasm32")))]
pub fn from_url<U: reqwest::IntoUrl>(url: U) -> Result<Self, Error> {
GtfsReader::default().raw().read_from_url(url)
}
#[cfg(feature = "read-url")]
pub async fn from_url_async<U: reqwest::IntoUrl>(url: U) -> Result<Self, Error> {
GtfsReader::default().raw().read_from_url_async(url).await
}
pub fn from_reader<T: std::io::Read + std::io::Seek>(reader: T) -> Result<Self, Error> {
GtfsReader::default().raw().read_from_reader(reader)
}
pub(crate) fn unknown_to_default(&mut self) {
if let Ok(stops) = &mut self.stops {
for stop in stops.iter_mut() {
if let LocationType::Unknown(_) = stop.location_type {
stop.location_type = LocationType::default();
}
if let Availability::Unknown(_) = stop.wheelchair_boarding {
stop.wheelchair_boarding = Availability::default();
}
}
}
if let Ok(stop_times) = &mut self.stop_times {
for stop_time in stop_times.iter_mut() {
if let PickupDropOffType::Unknown(_) = stop_time.pickup_type {
stop_time.pickup_type = PickupDropOffType::default();
}
if let PickupDropOffType::Unknown(_) = stop_time.drop_off_type {
stop_time.drop_off_type = PickupDropOffType::default();
}
if let ContinuousPickupDropOff::Unknown(_) = stop_time.continuous_pickup {
stop_time.continuous_pickup = ContinuousPickupDropOff::default();
}
if let ContinuousPickupDropOff::Unknown(_) = stop_time.continuous_drop_off {
stop_time.continuous_drop_off = ContinuousPickupDropOff::default();
}
}
}
if let Ok(trips) = &mut self.trips {
for trip in trips.iter_mut() {
if let Availability::Unknown(_) = trip.wheelchair_accessible {
trip.wheelchair_accessible = Availability::default();
}
if let BikesAllowedType::Unknown(_) = trip.bikes_allowed {
trip.bikes_allowed = BikesAllowedType::default();
}
}
}
}
}
fn mandatory_file_summary<T>(objs: &Result<Vec<T>, Error>) -> String {
match objs {
Ok(vec) => format!("{} objects", vec.len()),
Err(e) => format!("Could not read {e}"),
}
}
fn optional_file_summary<T>(objs: &Option<Result<Vec<T>, Error>>) -> String {
match objs {
Some(objs) => mandatory_file_summary(objs),
None => "File not present".to_string(),
}
}