[][src]Struct csv::index::Indexed

pub struct Indexed<R, I> { /* fields omitted */ }

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]

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 ith record.

This uses zero-based indexing, so seeking to the 0th 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 ByteStrings instead of Strings.

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 ByteStrings instead of Strings.

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

impl<R, I> Deref for Indexed<R, I>[src]

type Target = Reader<R>

The resulting type after dereferencing.

impl<R, I> DerefMut for Indexed<R, I>[src]

Auto Trait Implementations

impl<R, I> Send for Indexed<R, I> where
    I: Send,
    R: Send

impl<R, I> Sync for Indexed<R, I> where
    I: Sync,
    R: Sync

Blanket Implementations

impl<T> From for T[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.