···44- Add Pipeline select method
55- Add Pipeline `from_pipelines` constructor for merging pipelines together
66- Remember row order in transform_into
77+- Include source index in errors
7889## 0.2.0 - 2023 Jan 11
910- Add `Target` struct helper for creating targets, and hide the targets in the `target` module.
+22-8
src/headers.rs
···11-use crate::{Error, Row};
11+use crate::Row;
22use csv::StringRecordIter;
33use std::collections::BTreeMap;
44+use std::fmt;
4556/// The headers of a CSV file
67#[derive(Debug, Clone, PartialEq)]
···89 indexes: BTreeMap<String, usize>,
910 row: Row,
1011}
1212+pub enum RenameError {
1313+ DuplicateColumn(usize),
1414+ MissingColumn,
1515+}
1616+impl fmt::Display for RenameError {
1717+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1818+ match self {
1919+ RenameError::DuplicateColumn(index) => write!(f, "Duplicate column at index {}", index),
2020+ RenameError::MissingColumn => write!(f, "Missing column"),
2121+ }
2222+ }
2323+}
2424+1125impl Headers {
1226 pub fn new() -> Self {
1327 Headers {
···1731 }
18321933 /// Returns `Error::MissingColumn` if `from` is non-existant or `Error::DuplicateColumn` the new name already exists
2020- pub fn rename(&mut self, from: &str, to: &str) -> Result<(), Error> {
2121- if self.contains(to) {
2222- return Err(Error::DuplicateColumn(to.to_string()));
3434+ pub fn rename(&mut self, from: &str, to: &str) -> Result<(), RenameError> {
3535+ if let Some(index) = self.get_index(to) {
3636+ return Err(RenameError::DuplicateColumn(index));
2337 }
2438 let index = match self.indexes.remove(from) {
2539 Some(index) => index,
2626- None => return Err(Error::MissingColumn(from.to_string())),
4040+ None => return Err(RenameError::MissingColumn),
2741 };
2842 self.indexes.insert(to.to_string(), index);
2943 let mut row_vec: Vec<_> = self.row.into_iter().collect();
···6074 &self.row
6175 }
62766363- /// Returns `Error::DuplicateColumn` if a column is duplicated
6464- pub fn from_row(row: Row) -> Result<Self, Error> {
7777+ /// If a column is duplicated, errors with the column name
7878+ pub fn from_row(row: Row) -> Result<Self, String> {
6579 let mut header = Headers::new();
6680 for field in &row {
6781 let added = header.push_field(field);
6882 if !added {
6969- return Err(Error::DuplicateColumn(field.to_string()));
8383+ return Err(field.to_string());
7084 }
7185 }
7286 Ok(header)
+13-14
src/lib.rs
···113113pub type RowResult = Result<Row, Error>;
114114115115#[derive(Debug)]
116116-pub enum Error {
117117- /// cSV and IO errors are in here
116116+pub struct Error {
117117+ pub source: usize,
118118+ pub kind: ErrorKind,
119119+}
120120+impl Error {
121121+ pub fn new(source: usize, kind: ErrorKind) -> Error {
122122+ Error { source, kind }
123123+ }
124124+}
125125+126126+#[derive(Debug)]
127127+pub enum ErrorKind {
128128+ /// CSV and IO errors are in here.
118129 Csv(csv::Error),
119119- Io(std::io::Error),
120130 /// The column of this name is missing.
121131 MissingColumn(String),
122132 /// This column name appears twice.
···126136 /// Two pipeline sources don't have the same headers.
127137 MismatchedHeaders(Row, Row),
128138}
129129-impl From<csv::Error> for Error {
130130- fn from(error: csv::Error) -> Error {
131131- Error::Csv(error)
132132- }
133133-}
134134-135135-impl From<std::io::Error> for Error {
136136- fn from(error: std::io::Error) -> Error {
137137- Error::Io(error)
138138- }
139139-}