[−][src]Struct csv::index::Indexed
A type for representing CSV data with a basic record index.
The index is a sequence of 64 bit (8 bytes) integers, where each integer corresponds to the byte offset of the start of the corresponding record in the CSV data. This allows one to skip to any record in the CSV data and read it instantly.
Note that this type derefs to a &mut csv::Reader<R>
.
Methods
impl<R, I> Indexed<R, I> where
R: Read + Seek,
I: Read + Seek,
[src]
R: Read + Seek,
I: Read + Seek,
pub fn open(rdr: Reader<R>, idx: I) -> Result<Indexed<R, I>>
[src]
Opens a new index corresponding to the CSV reader given.
If the CSV reader has headers enabled, they are read first.
Note that there are no checks in place to make sure the index accurately represents the CSV reader given.
pub fn seek(&mut self, i: u64) -> Result<()>
[src]
Seeks to i
th record.
This uses zero-based indexing, so seeking to the 0
th record will read
the first record. (The first record may not be the first written row
in the CSV data if the underlying reader has headers enabled.)
An error is returned if the index given is greater than or equal to the number of records in the index.
pub fn count(&self) -> u64
[src]
Returns the number of CSV records in the index in O(1)
time.
Methods from Deref<Target = Reader<R>>
ⓘImportant traits for DecodedRecords<'a, R, D>pub fn decode<'a, D: Decodable>(&'a mut self) -> DecodedRecords<'a, R, D>
[src]
Uses type-based decoding to read a single record from CSV data.
The type that is being decoded into should correspond to one full
CSV record. A tuple, struct or Vec
fit this category. A tuple,
struct or Vec
should consist of primitive types like integers,
floats, characters and strings which map to single fields. If a field
cannot be decoded into the type requested, an error is returned.
Enums are also supported in a limited way. Namely, its variants must
have exactly 1
parameter each. Each variant decodes based on its
constituent type and variants are tried in the order that they appear
in their enum
definition. See below for examples.
Examples
This example shows how to decode records into a struct. (Note that currently, the names of the struct members are irrelevant.)
extern crate rustc_serialize; #[derive(RustcDecodable)] struct Pair { name1: String, name2: String, dist: u32, } let mut rdr = csv::Reader::from_string("foo,bar,1\nfoo,baz,2") .has_headers(false); // Instantiating a specific type when decoding is usually necessary. let rows = rdr.decode().collect::<csv::Result<Vec<Pair>>>().unwrap(); assert_eq!(rows[0].dist, 1); assert_eq!(rows[1].dist, 2);
We can get a little crazier with custon enum types or Option
types.
An Option
type in particular is useful when a column doesn't contain
valid data in every record (whether it be empty or malformed).
extern crate rustc_serialize; #[derive(RustcDecodable, PartialEq, Debug)] struct MyUint(u32); #[derive(RustcDecodable, PartialEq, Debug)] enum Number { Integer(i64), Float(f64) } #[derive(RustcDecodable)] struct Row { name1: String, name2: String, dist: Option<MyUint>, dist2: Number, } let mut rdr = csv::Reader::from_string("foo,bar,1,1\nfoo,baz,,1.5") .has_headers(false); let rows = rdr.decode().collect::<csv::Result<Vec<Row>>>().unwrap(); assert_eq!(rows[0].dist, Some(MyUint(1))); assert_eq!(rows[1].dist, None); assert_eq!(rows[0].dist2, Number::Integer(1)); assert_eq!(rows[1].dist2, Number::Float(1.5));
Finally, as a special case, a tuple/struct/Vec
can be used as the
"tail" of another tuple/struct/Vec
to capture all remaining fields:
extern crate rustc_serialize; #[derive(RustcDecodable)] struct Pair { name1: String, name2: String, attrs: Vec<u32>, } let mut rdr = csv::Reader::from_string("a,b,1,2,3,4\ny,z,5,6,7,8") .has_headers(false); let rows = rdr.decode().collect::<csv::Result<Vec<Pair>>>().unwrap(); assert_eq!(rows[0].attrs, vec![1,2,3,4]); assert_eq!(rows[1].attrs, vec![5,6,7,8]);
If a tuple/struct/Vec
appears any where other than the "tail" of a
record, then the behavior is undefined. (You'll likely get a runtime
error. I believe this is a limitation of the current decoding machinery
in the serialize
crate.)
ⓘImportant traits for StringRecords<'a, R>pub fn records<'a>(&'a mut self) -> StringRecords<'a, R>
[src]
Returns an iterator of records in the CSV data where each field is
a String
.
Example
This is your standard CSV interface with no type decoding magic.
let data = " sticker,mortals,7 bribed,personae,7 wobbling,poncing,4 interposed,emmett,9 chocolate,refile,7"; let mut rdr = csv::Reader::from_string(data).has_headers(false); for row in rdr.records() { let row = row.unwrap(); println!("{:?}", row); }
pub fn headers(&mut self) -> Result<Vec<String>>
[src]
Returns a copy of the first record in the CSV data as strings.
This method may be called at any time and regardless of whether
no_headers
is set or not.
Example
let mut rdr = csv::Reader::from_string("a,b,c\n1,2,3"); let headers1 = rdr.headers().unwrap(); let rows = rdr.records().collect::<csv::Result<Vec<_>>>().unwrap(); let headers2 = rdr.headers().unwrap(); let s = |s: &'static str| s.to_string(); assert_eq!(headers1, headers2); assert_eq!(headers1, vec![s("a"), s("b"), s("c")]); assert_eq!(rows.len(), 1); assert_eq!(rows[0], vec![s("1"), s("2"), s("3")]);
Note that if no_headers
is called on the CSV reader, the rows
returned in this example include the first record:
let mut rdr = csv::Reader::from_string("a,b,c\n1,2,3") .has_headers(false); let headers1 = rdr.headers().unwrap(); let rows = rdr.records().collect::<csv::Result<Vec<_>>>().unwrap(); let headers2 = rdr.headers().unwrap(); let s = |s: &'static str| s.to_string(); assert_eq!(headers1, headers2); assert_eq!(headers1, vec![s("a"), s("b"), s("c")]); // The header rows are now part of the record iterators. assert_eq!(rows.len(), 2); assert_eq!(rows[0], headers1); assert_eq!(rows[1], vec![s("1"), s("2"), s("3")]);
pub fn byte_headers(&mut self) -> Result<Vec<ByteString>>
[src]
This is just like headers
, except fields are ByteString
s instead
of String
s.
ⓘImportant traits for ByteRecords<'a, R>pub fn byte_records<'a>(&'a mut self) -> ByteRecords<'a, R>
[src]
This is just like records
, except fields are ByteString
s instead
of String
s.
pub fn done(&self) -> bool
[src]
Returns true
if the CSV parser has reached its final state. When
this method returns true
, all iterators will always return None
.
This is not needed in typical usage since the record iterators will stop for you when the parser completes. This method is useful when you're accessing the parser's lowest-level iterator.
Example
This is the fastest way to compute the number of records in CSV data using this crate. (It is fast because it does not allocate space for every field.)
let data = " sticker,mortals,7 bribed,personae,7 wobbling,poncing,4 interposed,emmett,9 chocolate,refile,7"; let mut rdr = csv::Reader::from_string(data); let mut count = 0u64; while !rdr.done() { loop { // This case analysis is necessary because we only want to // increment the count when `EndOfRecord` is seen. (If the // CSV data is empty, then it will never be emitted.) match rdr.next_bytes() { csv::NextField::EndOfCsv => break, csv::NextField::EndOfRecord => { count += 1; break; }, csv::NextField::Error(err) => panic!(err), csv::NextField::Data(_) => {} } } } assert_eq!(count, 5);
pub fn next_bytes(&mut self) -> NextField<[u8]>
[src]
An iterator over fields in the current record.
This provides low level access to CSV records as raw byte slices.
Namely, no allocation is performed. Unlike other iterators in this
crate, this yields fields instead of records. Notably, this cannot
implement the Iterator
trait safely. As such, it cannot be used with
a for
loop.
See the documentation for the NextField
type on how the iterator
works.
This iterator always returns all records (i.e., it won't skip the header row).
Example
This method is most useful when used in conjunction with the the
done
method:
let data = " sticker,mortals,7 bribed,personae,7 wobbling,poncing,4 interposed,emmett,9 chocolate,refile,7"; let mut rdr = csv::Reader::from_string(data); while !rdr.done() { while let Some(r) = rdr.next_bytes().into_iter_result() { print!("{:?} ", r.unwrap()); } println!(""); }
pub fn next_str(&mut self) -> NextField<str>
[src]
This is just like next_bytes
except it converts each field to
a Unicode string in place.
pub fn byte_offset(&self) -> u64
[src]
Returns the byte offset at which the current record started.
pub fn seek(&mut self, pos: u64) -> Result<()>
[src]
Seeks the underlying reader to the file cursor specified.
This comes with several caveats:
- The existing buffer is dropped and a new one is created.
- If you seek to a position other than the start of a record, you'll probably get an incorrect parse. (This is not unsafe.)
Mostly, this is intended for use with the index
sub module.
Note that if pos
is equivalent to the current parsed byte offset,
then no seeking is performed. (In this case, seek
is a no-op.)
Trait Implementations
Auto Trait Implementations
impl<R, I> Send for Indexed<R, I> where
I: Send,
R: Send,
I: Send,
R: Send,
impl<R, I> Sync for Indexed<R, I> where
I: Sync,
R: Sync,
I: Sync,
R: Sync,
Blanket Implementations
impl<T> From for T
[src]
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,