Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};

/// All the objects type from the GTFS specification that this library reads
#[derive(Debug, Serialize, Eq, PartialEq, Hash)]
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
pub enum ObjectType {
/// [Agency] <https://gtfs.org/reference/static/#agencytxt>
Agency,
Expand Down
33 changes: 26 additions & 7 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use thiserror::Error;

/// Specific line from a CSV file that could not be read
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct LineError {
/// Headers of the CSV file
pub headers: Vec<String>,
Expand All @@ -11,7 +11,7 @@ pub struct LineError {
}

/// An error that can occur when processing GTFS data.
#[derive(Error, Debug)]
#[derive(Error, Debug, Clone)]
pub enum Error {
/// A mandatory file is not present in the archive
#[error("Cound not find file {0}")]
Expand All @@ -30,32 +30,51 @@ pub enum Error {
InvalidColor(String),
/// Generic Input/Output error while reading a file
#[error("impossible to read file")]
IO(#[from] std::io::Error),
IO(std::sync::Arc<std::io::Error>),
/// Impossible to read a file
#[error("impossible to read '{file_name}'")]
NamedFileIO {
/// The file name that could not be read
file_name: String,
/// The inital error that caused the unability to read the file
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
source: std::sync::Arc<dyn std::error::Error + Send + Sync>,
},
/// Impossible to fetch the remote archive by the URL
#[cfg(feature = "read-url")]
#[error("impossible to remotely access file")]
Fetch(#[from] reqwest::Error),
Fetch(std::sync::Arc<reqwest::Error>),
/// Impossible to read a CSV file
#[error("impossible to read csv file '{file_name}'")]
CSVError {
/// File name that could not be parsed as CSV
file_name: String,
/// The initial error by the csv library
#[source]
source: csv::Error,
source: std::sync::Arc<csv::Error>,
/// The line that could not be parsed by the csv library
line_in_error: Option<LineError>,
},
/// Error when trying to unzip the GTFS archive
#[error(transparent)]
Zip(#[from] zip::result::ZipError),
Zip(std::sync::Arc<zip::result::ZipError>),
}

impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Error::IO(std::sync::Arc::new(err))
}
}

#[cfg(feature = "read-url")]
impl From<reqwest::Error> for Error {
fn from(err: reqwest::Error) -> Self {
Error::Fetch(std::sync::Arc::new(err))
}
}

impl From<zip::result::ZipError> for Error {
fn from(err: zip::result::ZipError) -> Self {
Error::Zip(std::sync::Arc::new(err))
}
}
2 changes: 1 addition & 1 deletion src/gtfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use web_time::{Duration, Instant};
/// ```
///
/// The [StopTime] are accessible from the [Trip]
#[derive(Default)]
#[derive(Default, Clone)]
pub struct Gtfs {
/// Time needed to read and parse the archive
pub read_duration: Duration,
Expand Down
12 changes: 6 additions & 6 deletions src/gtfs_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ impl RawGtfsReader {
.read_exact(&mut bom)
.map_err(|e| Error::NamedFileIO {
file_name: file_name.to_owned(),
source: Box::new(e),
source: std::sync::Arc::new(e),
})?;

let chained = if bom != [0xefu8, 0xbbu8, 0xbfu8] {
Expand All @@ -374,7 +374,7 @@ impl RawGtfsReader {
.headers()
.map_err(|e| Error::CSVError {
file_name: file_name.to_owned(),
source: e,
source: std::sync::Arc::new(e),
line_in_error: None,
})?
.clone()
Expand All @@ -389,14 +389,14 @@ impl RawGtfsReader {
// Read each record into the pre-allocated StringRecord one at a time
while reader.read_record(&mut rec).map_err(|e| Error::CSVError {
file_name: file_name.to_owned(),
source: e,
source: std::sync::Arc::new(e),
line_in_error: None,
})? {
let obj = rec
.deserialize(Some(&headers))
.map_err(|e| Error::CSVError {
file_name: file_name.to_owned(),
source: e,
source: std::sync::Arc::new(e),
line_in_error: Some(crate::error::LineError {
headers: headers.into_iter().map(String::from).collect(),
values: rec.into_iter().map(String::from).collect(),
Expand All @@ -420,7 +420,7 @@ impl RawGtfsReader {
File::open(path)
.map_err(|e| Error::NamedFileIO {
file_name: file_name.to_owned(),
source: Box::new(e),
source: std::sync::Arc::new(e),
})
.and_then(|r| self.read_objs(r, &file_name))
} else {
Expand Down Expand Up @@ -469,7 +469,7 @@ impl RawGtfsReader {
self.read_objs(
archive.by_index(*i).map_err(|e| Error::NamedFileIO {
file_name: file_name.to_owned(),
source: Box::new(e),
source: std::sync::Arc::new(e),
})?,
file_name,
)
Expand Down
2 changes: 1 addition & 1 deletion src/raw_gtfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use web_time::Duration;
///
/// This is used to analyze the GTFS and detect anomalies
/// To manipulate the transit data, maybe [crate::Gtfs] will be more convienient
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct RawGtfs {
/// Time needed to read and parse the archive
pub read_duration: Duration,
Expand Down