diff --git a/src/enums.rs b/src/enums.rs index 516e514..95ec8e5 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -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] Agency, diff --git a/src/error.rs b/src/error.rs index 7ec098d..f10cf1b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -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, @@ -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}")] @@ -30,7 +30,7 @@ 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), /// Impossible to read a file #[error("impossible to read '{file_name}'")] NamedFileIO { @@ -38,12 +38,12 @@ pub enum Error { file_name: String, /// The inital error that caused the unability to read the file #[source] - source: Box, + source: std::sync::Arc, }, /// 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), /// Impossible to read a CSV file #[error("impossible to read csv file '{file_name}'")] CSVError { @@ -51,11 +51,30 @@ pub enum Error { file_name: String, /// The initial error by the csv library #[source] - source: csv::Error, + source: std::sync::Arc, /// The line that could not be parsed by the csv library line_in_error: Option, }, /// Error when trying to unzip the GTFS archive #[error(transparent)] - Zip(#[from] zip::result::ZipError), + Zip(std::sync::Arc), +} + +impl From for Error { + fn from(err: std::io::Error) -> Self { + Error::IO(std::sync::Arc::new(err)) + } +} + +#[cfg(feature = "read-url")] +impl From for Error { + fn from(err: reqwest::Error) -> Self { + Error::Fetch(std::sync::Arc::new(err)) + } +} + +impl From for Error { + fn from(err: zip::result::ZipError) -> Self { + Error::Zip(std::sync::Arc::new(err)) + } } diff --git a/src/gtfs.rs b/src/gtfs.rs index 9d7f608..b6721ab 100644 --- a/src/gtfs.rs +++ b/src/gtfs.rs @@ -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, diff --git a/src/gtfs_reader.rs b/src/gtfs_reader.rs index 39e556f..f189e4e 100644 --- a/src/gtfs_reader.rs +++ b/src/gtfs_reader.rs @@ -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] { @@ -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() @@ -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(), @@ -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 { @@ -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, ) diff --git a/src/raw_gtfs.rs b/src/raw_gtfs.rs index f6e53d9..18e63b6 100644 --- a/src/raw_gtfs.rs +++ b/src/raw_gtfs.rs @@ -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,