From d3d2f67fbf8765b326778f19c2866bac386a74b9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 8 Jan 2025 13:02:43 -0500 Subject: [PATCH] Refactor the lifetimes for more flexibility --- src/lib.rs | 2 +- src/loader.rs | 35 +++++++++++++++++++++++++++++------ src/main.rs | 4 +++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e21ac8cb..070b4ce7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,3 @@ pub mod loader; -pub use crate::loader::{CsvLoader, ExactSizeIterable, Loader}; +pub use crate::loader::{CsvLoader, Loader, Record}; diff --git a/src/loader.rs b/src/loader.rs index 62c7a791..e48acd2f 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -1,18 +1,41 @@ use std::fs::File; -use std::iter; -pub trait ExactSizeIterable { - fn iter(&self) -> impl iter::ExactSizeIterator; +pub trait AsRef<'a, T> +where + T: ?Sized, +{ + fn as_ref(&self) -> &'a T; } -impl ExactSizeIterable for csv::ByteRecord { - fn iter(&self) -> impl iter::ExactSizeIterator { +impl<'a> AsRef<'a, [u8]> for &'a [u8] { + fn as_ref(&self) -> &'a [u8] { + self + } +} + +pub trait Record { + type Item<'a>: AsRef<'a, [u8]> + where + Self: 'a; + + type Iter<'a>: ExactSizeIterator> + where + Self: 'a; + + fn iter(&self) -> Self::Iter<'_>; +} + +impl Record for csv::ByteRecord { + type Item<'a> = &'a [u8]; + type Iter<'a> = csv::ByteRecordIter<'a>; + + fn iter(&self) -> Self::Iter<'_> { self.into_iter() } } pub trait Loader { - type RecordType: ExactSizeIterable; + type RecordType: Record; /// Name of the resource we're loading from (e.g., a file path). fn name(&self) -> &str; diff --git a/src/main.rs b/src/main.rs index 11cfd1d1..c4cfa156 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,8 @@ use clap::Parser; use std::iter; use std::sync::LazyLock; -use csvsql::ExactSizeIterable; +use csvsql::loader::AsRef; +use csvsql::Record; fn normalize_col(col: &str) -> String { static RE: LazyLock = LazyLock::new(|| regex::Regex::new(r"\(.*?\)$").unwrap()); @@ -92,6 +93,7 @@ fn _load_table_from_loader( let record = record?; let row = record.iter(); let row_len = row.len(); + let row = row.map(|v| v.as_ref()); if row_len > normalized_cols.len() { anyhow::bail!( "Too many fields on row {}, fields: {:?}",