gtfs_structures/
raw_gtfs.rs1use crate::Error;
2use crate::GtfsReader;
3use crate::objects::*;
4use std::path::Path;
5use web_time::Duration;
6
7#[derive(Debug)]
12pub struct RawGtfs {
13 pub read_duration: Duration,
15 pub calendar: Option<Result<Vec<Calendar>, Error>>,
17 pub calendar_dates: Option<Result<Vec<CalendarDate>, Error>>,
19 pub stops: Result<Vec<Stop>, Error>,
21 pub routes: Result<Vec<Route>, Error>,
23 pub trips: Result<Vec<RawTrip>, Error>,
25 pub agencies: Result<Vec<Agency>, Error>,
27 pub shapes: Option<Result<Vec<Shape>, Error>>,
29 pub fare_attributes: Option<Result<Vec<FareAttribute>, Error>>,
31 pub fare_rules: Option<Result<Vec<FareRule>, Error>>,
33 pub fare_products: Option<Result<Vec<FareProduct>, Error>>,
35 pub fare_media: Option<Result<Vec<FareMedia>, Error>>,
37 pub rider_categories: Option<Result<Vec<RiderCategory>, Error>>,
39 pub frequencies: Option<Result<Vec<RawFrequency>, Error>>,
41 pub transfers: Option<Result<Vec<RawTransfer>, Error>>,
43 pub pathways: Option<Result<Vec<RawPathway>, Error>>,
45 pub feed_info: Option<Result<Vec<FeedInfo>, Error>>,
47 pub stop_times: Result<Vec<RawStopTime>, Error>,
49 pub files: Vec<String>,
51 pub source_format: SourceFormat,
53 pub sha256: Option<String>,
55 pub translations: Option<Result<Vec<RawTranslation>, Error>>,
57 pub ticketing_deep_links: Option<Result<Vec<TicketingDeepLink>, Error>>,
59 pub ticketing_identifiers: Option<Result<Vec<TicketingIdentifier>, Error>>,
61 pub attributions: Option<Result<Vec<Attribution>, Error>>,
63}
64
65impl RawGtfs {
66 pub fn print_stats(&self) {
68 println!("GTFS data:");
69 println!(" Read in {:?}", self.read_duration);
70 println!(" Stops: {}", mandatory_file_summary(&self.stops));
71 println!(" Routes: {}", mandatory_file_summary(&self.routes));
72 println!(" Trips: {}", mandatory_file_summary(&self.trips));
73 println!(" Agencies: {}", mandatory_file_summary(&self.agencies));
74 println!(" Stop times: {}", mandatory_file_summary(&self.stop_times));
75 println!(" Shapes: {}", optional_file_summary(&self.shapes));
76 println!(" Fares: {}", optional_file_summary(&self.fare_attributes));
77 println!(
78 " Frequencies: {}",
79 optional_file_summary(&self.frequencies)
80 );
81 println!(" Transfers: {}", optional_file_summary(&self.transfers));
82 println!(" Pathways: {}", optional_file_summary(&self.pathways));
83 println!(" Feed info: {}", optional_file_summary(&self.feed_info));
84 println!(
85 " Translations: {}",
86 optional_file_summary(&self.translations)
87 );
88 println!(
89 " Ticketing deep links: {}",
90 optional_file_summary(&self.ticketing_deep_links)
91 );
92 println!(
93 " Ticketing identifiers: {}",
94 optional_file_summary(&self.ticketing_identifiers)
95 );
96 println!(
97 " Attributions: {}",
98 optional_file_summary(&self.attributions)
99 );
100 }
101
102 #[cfg(not(target_arch = "wasm32"))]
107 pub fn new(gtfs: &str) -> Result<Self, Error> {
108 GtfsReader::default().raw().read(gtfs)
109 }
110
111 pub fn from_path<P>(path: P) -> Result<Self, Error>
113 where
114 P: AsRef<Path>,
115 {
116 GtfsReader::default().raw().read_from_path(path)
117 }
118
119 #[cfg(all(feature = "read-url", not(target_arch = "wasm32")))]
123 pub fn from_url<U: reqwest::IntoUrl>(url: U) -> Result<Self, Error> {
124 GtfsReader::default().raw().read_from_url(url)
125 }
126
127 #[cfg(feature = "read-url")]
131 pub async fn from_url_async<U: reqwest::IntoUrl>(url: U) -> Result<Self, Error> {
132 GtfsReader::default().raw().read_from_url_async(url).await
133 }
134
135 pub fn from_reader<T: std::io::Read + std::io::Seek>(reader: T) -> Result<Self, Error> {
139 GtfsReader::default().raw().read_from_reader(reader)
140 }
141
142 pub(crate) fn unknown_to_default(&mut self) {
143 if let Ok(stops) = &mut self.stops {
144 for stop in stops.iter_mut() {
145 if let LocationType::Unknown(_) = stop.location_type {
146 stop.location_type = LocationType::default();
147 }
148 if let Availability::Unknown(_) = stop.wheelchair_boarding {
149 stop.wheelchair_boarding = Availability::default();
150 }
151 }
152 }
153 if let Ok(stop_times) = &mut self.stop_times {
154 for stop_time in stop_times.iter_mut() {
155 if let PickupDropOffType::Unknown(_) = stop_time.pickup_type {
156 stop_time.pickup_type = PickupDropOffType::default();
157 }
158 if let PickupDropOffType::Unknown(_) = stop_time.drop_off_type {
159 stop_time.drop_off_type = PickupDropOffType::default();
160 }
161 if let ContinuousPickupDropOff::Unknown(_) = stop_time.continuous_pickup {
162 stop_time.continuous_pickup = ContinuousPickupDropOff::default();
163 }
164 if let ContinuousPickupDropOff::Unknown(_) = stop_time.continuous_drop_off {
165 stop_time.continuous_drop_off = ContinuousPickupDropOff::default();
166 }
167 }
168 }
169 if let Ok(trips) = &mut self.trips {
170 for trip in trips.iter_mut() {
171 if let Availability::Unknown(_) = trip.wheelchair_accessible {
172 trip.wheelchair_accessible = Availability::default();
173 }
174 if let BikesAllowedType::Unknown(_) = trip.bikes_allowed {
175 trip.bikes_allowed = BikesAllowedType::default();
176 }
177 }
178 }
179 }
180}
181
182fn mandatory_file_summary<T>(objs: &Result<Vec<T>, Error>) -> String {
183 match objs {
184 Ok(vec) => format!("{} objects", vec.len()),
185 Err(e) => format!("Could not read {e}"),
186 }
187}
188
189fn optional_file_summary<T>(objs: &Option<Result<Vec<T>, Error>>) -> String {
190 match objs {
191 Some(objs) => mandatory_file_summary(objs),
192 None => "File not present".to_string(),
193 }
194}