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
11 changes: 6 additions & 5 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ extern crate quick_csv as csv;
extern crate rustc_serialize;
extern crate test;

use csv::Csv;
use std::fmt::{Debug, Display};
use std::fs;
use std::io::Read;
use test::Bencher;
use csv::Csv;

static CSV_DATA: &'static str = "./examples/data/bench.csv";

fn ordie<T, E: Debug+Display>(r: Result<T, E>) -> T {
r.or_else(|e: E| -> Result<T, E> { panic!(format!("{:?}", e)) }).unwrap()
fn ordie<T, E: Debug + Display>(r: Result<T, E>) -> T {
r.or_else(|e: E| -> Result<T, E> { panic!(format!("{:?}", e)) })
.unwrap()
}

fn file_to_mem(fp: &str) -> Vec<u8> {
Expand All @@ -31,7 +32,7 @@ fn str_records(b: &mut Bencher) {
let dec = Csv::from_reader(&*data);
for row in dec.into_iter() {
for c in row.unwrap().columns() {
let _ = c;
let _ = c;
}
}
})
Expand All @@ -45,7 +46,7 @@ fn bytes_records(b: &mut Bencher) {
let dec = Csv::from_reader(&*data);
for row in dec.into_iter() {
for c in row.unwrap().bytes_columns() {
let _ = c;
let _ = c;
}
}
})
Expand Down
198 changes: 139 additions & 59 deletions src/columns.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! Column management module
//!
//!
//! Provides convenient or fast column conversions
//! Deserialize columns into a `Decodable` type

use std::str::FromStr;
use error::{Error, Result};
use rustc_serialize as serialize;
use error::{Result, Error};
use std::slice::Iter;
use std::str::FromStr;

/// Iterator over bytes slice of columns
pub struct BytesColumns<'a> {
Expand All @@ -22,14 +22,17 @@ impl<'a> Iterator for BytesColumns<'a> {
self.iter.next().map(|p| {
let s = &self.line[self.pos..*p];
self.pos = *p + 1;
if s.starts_with(&[b'\"']) { &s[1..s.len() - 1] } else { s }
if s.starts_with(&[b'\"']) {
&s[1..s.len() - 1]
} else {
s
}
})
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}

}

impl<'a> ExactSizeIterator for BytesColumns<'a> {
Expand All @@ -39,16 +42,14 @@ impl<'a> ExactSizeIterator for BytesColumns<'a> {
}

impl<'a> BytesColumns<'a> {

/// Creates a new BytesColumns iterator
pub fn new(line: &'a [u8], cols: &'a [usize]) -> BytesColumns<'a> {
BytesColumns {
pos: 0,
line: line,
line,
iter: cols.iter(),
}
}

}

/// &str iterator on columns
Expand All @@ -65,14 +66,17 @@ impl<'a> Iterator for Columns<'a> {
self.iter.next().map(|p| {
let s = &self.line[self.pos..*p];
self.pos = *p + 1;
if s.starts_with('\"') { &s[1..s.len() - 1] } else { s }
if s.starts_with('\"') {
&s[1..s.len() - 1]
} else {
s
}
})
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}

}

impl<'a> ExactSizeIterator for Columns<'a> {
Expand All @@ -82,38 +86,47 @@ impl<'a> ExactSizeIterator for Columns<'a> {
}

impl<'a> Columns<'a> {

/// Creates a new Columns iterator
pub fn new(line: &'a str, cols: &'a [usize]) -> Columns<'a> {
Columns {
pos: 0,
line: line,
line,
iter: cols.iter(),
}
}

fn peek(&self) -> Option<&'a str> {
self.iter.clone().next().map(|p| {
let s = &self.line[self.pos..*p];
if s.starts_with('\"') { &s[1..s.len() - 1] } else { s }
if s.starts_with('\"') {
&s[1..s.len() - 1]
} else {
s
}
})
}

fn next_str<T>(&mut self) -> Result<T>
where T: FromStr + ::std::fmt::Debug,
T::Err: ::std::fmt::Debug
where
T: FromStr + ::std::fmt::Debug,
T::Err: ::std::fmt::Debug,
{
self.next().ok_or(Error::EOL).and_then(|col|
FromStr::from_str(col).map_err(|e|
Error::Decode(format!("Failed converting {}th column (\'{}\'):\n\t{:?}",
self.len(), col, e))))
self.next().ok_or(Error::EOL).and_then(|col| {
FromStr::from_str(col).map_err(|e| {
Error::Decode(format!(
"Failed converting {}th column (\'{}\'):\n\t{:?}",
self.len(),
col,
e
))
})
})
}

/// Deserializes a Columns iterator into any Decodable type
pub fn decode<T: serialize::Decodable>(&mut self) -> Result<T> {
serialize::Decodable::decode(self)
}

}

impl<'a> serialize::Decoder for Columns<'a> {
Expand All @@ -122,86 +135,143 @@ impl<'a> serialize::Decoder for Columns<'a> {
fn error(&mut self, err: &str) -> Error {
Error::Decode(err.into())
}
fn read_nil(&mut self) -> Result<()> { unimplemented!() }
fn read_usize(&mut self) -> Result<usize> { self.next_str() }
fn read_u64(&mut self) -> Result<u64> { self.next_str() }
fn read_u32(&mut self) -> Result<u32> { self.next_str() }
fn read_u16(&mut self) -> Result<u16> { self.next_str() }
fn read_u8(&mut self) -> Result<u8> { self.next_str() }
fn read_isize(&mut self) -> Result<isize> { self.next_str() }
fn read_i64(&mut self) -> Result<i64> { self.next_str() }
fn read_i32(&mut self) -> Result<i32> { self.next_str() }
fn read_i16(&mut self) -> Result<i16> { self.next_str() }
fn read_i8(&mut self) -> Result<i8> { self.next_str() }
fn read_bool(&mut self) -> Result<bool> { self.next_str() }
fn read_f64(&mut self) -> Result<f64> { self.next_str() }
fn read_f32(&mut self) -> Result<f32> { self.next_str() }
fn read_nil(&mut self) -> Result<()> {
unimplemented!()
}
fn read_usize(&mut self) -> Result<usize> {
self.next_str()
}
fn read_u64(&mut self) -> Result<u64> {
self.next_str()
}
fn read_u32(&mut self) -> Result<u32> {
self.next_str()
}
fn read_u16(&mut self) -> Result<u16> {
self.next_str()
}
fn read_u8(&mut self) -> Result<u8> {
self.next_str()
}
fn read_isize(&mut self) -> Result<isize> {
self.next_str()
}
fn read_i64(&mut self) -> Result<i64> {
self.next_str()
}
fn read_i32(&mut self) -> Result<i32> {
self.next_str()
}
fn read_i16(&mut self) -> Result<i16> {
self.next_str()
}
fn read_i8(&mut self) -> Result<i8> {
self.next_str()
}
fn read_bool(&mut self) -> Result<bool> {
self.next_str()
}
fn read_f64(&mut self) -> Result<f64> {
self.next_str()
}
fn read_f32(&mut self) -> Result<f32> {
self.next_str()
}
fn read_char(&mut self) -> Result<char> {
let col = try!(self.next().ok_or(Error::EOL));
let col = self.next().ok_or(Error::EOL)?;
if col.len() != 1 {
return Err(Error::Decode(format!(
"Expected a single char, found {} chars", col.len())));
"Expected a single char, found {} chars",
col.len()
)));
}
Ok(col.chars().next().unwrap())
}
fn read_str(&mut self) -> Result<String> { self.next_str() }
fn read_str(&mut self) -> Result<String> {
self.next_str()
}
fn read_enum<T, F>(&mut self, _: &str, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}

fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> Result<T>
where F: FnMut(&mut Columns<'a>, usize) -> Result<T> {
let i = try!(self
where
F: FnMut(&mut Columns<'a>, usize) -> Result<T>,
{
let i = self
.peek()
.and_then(|name| names.iter().position(|&n| n == name))
.ok_or(Error::Decode(format!(
"Could not load value into any variant in {:?}", names))));
"Could not load value into any variant in {:?}",
names
)))?;
let _ = self.next();
f(self, i)
}

fn read_enum_variant_arg<T, F>(&mut self, _: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}
fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T>
where F: FnMut(&mut Columns<'a>, usize) -> Result<T> {
where
F: FnMut(&mut Columns<'a>, usize) -> Result<T>,
{
self.read_enum_variant(names, f)
}
fn read_enum_struct_variant_field<T, F>(&mut self, _: &str,
f_idx: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
fn read_enum_struct_variant_field<T, F>(&mut self, _: &str, f_idx: usize, f: F) -> Result<T>
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
self.read_enum_variant_arg(f_idx, f)
}
fn read_struct<T, F>(&mut self, _: &str, _: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}
fn read_struct_field<T, F>(&mut self, _: &str, _: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}
fn read_tuple<T, F>(&mut self, _: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}
fn read_tuple_arg<T, F>(&mut self, _: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}
fn read_tuple_struct<T, F>(&mut self, _: &str, _: usize, _: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
unimplemented!()
}
fn read_tuple_struct_arg<T, F>(&mut self, _: usize, _: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
unimplemented!()
}

fn read_option<T, F>(&mut self, mut f: F) -> Result<T>
where F: FnMut(&mut Columns<'a>, bool) -> Result<T> {
let col = try!(self.peek().ok_or(Error::EOL));
where
F: FnMut(&mut Columns<'a>, bool) -> Result<T>,
{
let col = self.peek().ok_or(Error::EOL)?;
if col.is_empty() {
let _ = self.iter.next();
f(self, false)
Expand All @@ -211,24 +281,34 @@ impl<'a> serialize::Decoder for Columns<'a> {
}

fn read_seq<T, F>(&mut self, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>, usize) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>, usize) -> Result<T>,
{
let len = self.iter.clone().count();
f(self, len)
}
fn read_seq_elt<T, F>(&mut self, _: usize, f: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
f(self)
}
fn read_map<T, F>(&mut self, _: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>, usize) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>, usize) -> Result<T>,
{
unimplemented!()
}
fn read_map_elt_key<T, F>(&mut self, _: usize, _: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
unimplemented!()
}
fn read_map_elt_val<T, F>(&mut self, _: usize, _: F) -> Result<T>
where F: FnOnce(&mut Columns<'a>) -> Result<T> {
where
F: FnOnce(&mut Columns<'a>) -> Result<T>,
{
unimplemented!()
}
}
Loading