pub struct AsyncReaderBuilder { /* private fields */ }
Expand description

Builds a CSV reader with various configuration knobs.

This builder can be used to tweak the field delimiter, record terminator and more. Once a CSV reader / deserializer is built, its configuration cannot be changed.

Implementations§

source§

impl AsyncReaderBuilder

source

pub fn create_reader<R: AsyncRead + Unpin + Send>( &self, rdr: R ) -> AsyncReader<R>

Build a CSV reader from this configuration that reads data from rdr.

Note that the CSV reader is buffered automatically, so you should not wrap rdr in a buffered reader.

Example
use std::error::Error;
use csv_async::AsyncReaderBuilder;
use tokio_stream::StreamExt;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,United States,4628910
Concord,United States,42695
";
    let mut rdr = AsyncReaderBuilder::new().create_reader(data.as_bytes());
    let mut records = rdr.into_records();
    while let Some(record) = records.next().await {
        println!("{:?}", record?);
    }
    Ok(())
}
source§

impl AsyncReaderBuilder

source

pub fn new() -> AsyncReaderBuilder

Create a new builder for configuring CSV parsing.

To convert a builder into a reader, call one of the methods starting with from_.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::{AsyncReaderBuilder, StringRecord};

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,United States,4628910
Concord,United States,42695
";
    let mut rdr = AsyncReaderBuilder::new().create_reader(data.as_bytes());

    let records = rdr
        .records()
        .map(Result::unwrap)
        .collect::<Vec<StringRecord>>().await;
    assert_eq!(records, vec![
        vec!["Boston", "United States", "4628910"],
        vec!["Concord", "United States", "42695"],
    ]);
    Ok(())
}
source

pub fn delimiter(&mut self, delimiter: u8) -> &mut AsyncReaderBuilder

The field delimiter to use when parsing CSV.

The default is b','.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::{AsyncReaderBuilder, StringRecord};

async fn example() {
    let data = "\
city;country;pop
Boston;United States;4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .delimiter(b';')
        .create_reader(data.as_bytes());

    let records = rdr
        .records()
        .map(Result::unwrap)
        .collect::<Vec<StringRecord>>().await;
    assert_eq!(records, vec![
        vec!["Boston", "United States", "4628910"],
    ]);
}
source

pub fn has_headers(&mut self, yes: bool) -> &mut AsyncReaderBuilder

Whether to treat the first row as a special header row.

By default, the first row is treated as a special header row, which means the header is never returned by any of the record reading methods or iterators. When this is disabled (yes set to false), the first row is not treated specially.

Note that the headers and byte_headers methods are unaffected by whether this is set. Those methods always return the first record.

Example

This example shows what happens when has_headers is disabled. Namely, the first row is treated just like any other row.

use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,United States,4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .has_headers(false)
        .create_reader(data.as_bytes());
    let mut iter = rdr.records();

    // Read the first record.
    assert_eq!(iter.next().await.unwrap()?, vec!["city", "country", "pop"]);

    // Read the second record.
    assert_eq!(iter.next().await.unwrap()?, vec!["Boston", "United States", "4628910"]);

    assert!(iter.next().await.is_none());
    Ok(())
}
source

pub fn flexible(&mut self, yes: bool) -> &mut AsyncReaderBuilder

Whether the number of fields in records is allowed to change or not.

When disabled (which is the default), parsing CSV data will return an error if a record is found with a number of fields different from the number of fields in a previous record.

When enabled, this error checking is turned off.

Example: flexible records enabled
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    // Notice that the first row is missing the population count.
    let data = "\
city,country,pop
Boston,United States
";
    let mut rdr = AsyncReaderBuilder::new()
        .flexible(true)
        .create_reader(data.as_bytes());
    let mut records = rdr.records();
    assert_eq!(records.next().await.unwrap()?, vec!["Boston", "United States"]);
    Ok(())
}
Example: flexible records disabled

This shows the error that appears when records of unequal length are found and flexible records have been disabled (which is the default).

use std::error::Error;
use futures::stream::StreamExt;
use csv_async::{ErrorKind, AsyncReaderBuilder};

async fn example() -> Result<(), Box<dyn Error>> {
    // Notice that the first row is missing the population count.
    let data = "\
city,country,pop
Boston,United States
";
    let mut rdr = AsyncReaderBuilder::new()
        .flexible(false)
        .create_reader(data.as_bytes());

    let mut records = rdr.records();
    match records.next().await {
        Some(Err(err)) => match *err.kind() {
            ErrorKind::UnequalLengths { expected_len, len, .. } => {
                // The header row has 3 fields...
                assert_eq!(expected_len, 3);
                // ... but the first row has only 2 fields.
                assert_eq!(len, 2);
                Ok(())
            }
            ref wrong => {
                Err(From::from(format!(
                    "expected UnequalLengths error but got {:?}",
                    wrong)))
            }
        }
        Some(Ok(rec)) =>
            Err(From::from(format!(
                "expected one errored record but got good record {:?}",
                 rec))),
        None =>
           Err(From::from(
               "expected one errored record but got none"))
    }
}
source

pub fn end_on_io_error(&mut self, yes: bool) -> &mut AsyncReaderBuilder

If set, CSV records’ stream will end when first i/o error happens. Otherwise CSV reader will continue trying to read from underlying reader. For sample, please see unit test behavior_on_io_errors in following source file.

By default this option is set.

source

pub fn trim(&mut self, trim: Trim) -> &mut AsyncReaderBuilder

Whether fields are trimmed of leading and trailing whitespace or not.

By default, no trimming is performed. This method permits one to override that behavior and choose one of the following options:

  1. Trim::Headers trims only header values.
  2. Trim::Fields trims only non-header or “field” values.
  3. Trim::All trims both header and non-header values.

A value is only interpreted as a header value if this CSV reader is configured to read a header record (which is the default).

When reading string records, characters meeting the definition of Unicode whitespace are trimmed. When reading byte records, characters meeting the definition of ASCII whitespace are trimmed. ASCII whitespace characters correspond to the set [\t\n\v\f\r ].

Example

This example shows what happens when all values are trimmed.

use std::error::Error;
use futures::stream::StreamExt;
use csv_async::{AsyncReaderBuilder, StringRecord, Trim};

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city ,   country ,  pop
Boston,\"
   United States\",4628910
Concord,   United States   ,42695
";
    let mut rdr = AsyncReaderBuilder::new()
        .trim(Trim::All)
        .create_reader(data.as_bytes());
    let records = rdr
        .records()
        .map(Result::unwrap)
        .collect::<Vec<StringRecord>>().await;
    assert_eq!(records, vec![
        vec!["Boston", "United States", "4628910"],
        vec!["Concord", "United States", "42695"],
    ]);
    Ok(())
}
source

pub fn terminator(&mut self, term: Terminator) -> &mut AsyncReaderBuilder

The record terminator to use when parsing CSV.

A record terminator can be any single byte. The default is a special value, Terminator::CRLF, which treats any occurrence of \r, \n or \r\n as a single record terminator.

Example: $ as a record terminator
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::{AsyncReaderBuilder, Terminator};

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "city,country,pop$Boston,United States,4628910";
    let mut rdr = AsyncReaderBuilder::new()
        .terminator(Terminator::Any(b'$'))
        .create_reader(data.as_bytes());
    let mut iter = rdr.records();
    assert_eq!(iter.next().await.unwrap()?, vec!["Boston", "United States", "4628910"]);
    assert!(iter.next().await.is_none());
    Ok(())
}
source

pub fn quote(&mut self, quote: u8) -> &mut AsyncReaderBuilder

The quote character to use when parsing CSV.

The default is b'"'.

Example: single quotes instead of double quotes
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,'United States',4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .quote(b'\'')
        .create_reader(data.as_bytes());
    let mut iter = rdr.records();
    assert_eq!(iter.next().await.unwrap()?, vec!["Boston", "United States", "4628910"]);
    assert!(iter.next().await.is_none());
    Ok(())
}
source

pub fn escape(&mut self, escape: Option<u8>) -> &mut AsyncReaderBuilder

The escape character to use when parsing CSV.

In some variants of CSV, quotes are escaped using a special escape character like \ (instead of escaping quotes by doubling them).

By default, recognizing these idiosyncratic escapes is disabled.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,\"The \\\"United\\\" States\",4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .escape(Some(b'\\'))
        .create_reader(data.as_bytes());
    let mut records = rdr.records();
    assert_eq!(records.next().await.unwrap()?, vec!["Boston", "The \"United\" States", "4628910"]);
    Ok(())
}
source

pub fn double_quote(&mut self, yes: bool) -> &mut AsyncReaderBuilder

Enable double quote escapes.

This is enabled by default, but it may be disabled. When disabled, doubled quotes are not interpreted as escapes.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,\"The \"\"United\"\" States\",4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .double_quote(false)
        .create_reader(data.as_bytes());
    let mut records = rdr.records();
    assert_eq!(records.next().await.unwrap()?, vec!["Boston", "The \"United\"\" States\"", "4628910"]);
    Ok(())
}
source

pub fn quoting(&mut self, yes: bool) -> &mut AsyncReaderBuilder

Enable or disable quoting.

This is enabled by default, but it may be disabled. When disabled, quotes are not treated specially.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
Boston,\"The United States,4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .quoting(false)
        .create_reader(data.as_bytes());
    let mut records = rdr.records();
    assert_eq!(records.next().await.unwrap()?, vec!["Boston", "\"The United States", "4628910"]);
    Ok(())
}
source

pub fn comment(&mut self, comment: Option<u8>) -> &mut AsyncReaderBuilder

The comment character to use when parsing CSV.

If the start of a record begins with the byte given here, then that line is ignored by the CSV parser.

This is disabled by default.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city,country,pop
#Concord,United States,42695
Boston,United States,4628910
";
    let mut rdr = AsyncReaderBuilder::new()
        .comment(Some(b'#'))
        .create_reader(data.as_bytes());
    let mut records = rdr.records();
    assert_eq!(records.next().await.unwrap()?, vec!["Boston", "United States", "4628910"]);
    assert!(records.next().await.is_none());
    Ok(())
}
source

pub fn ascii(&mut self) -> &mut AsyncReaderBuilder

A convenience method for specifying a configuration to read ASCII delimited text.

This sets the delimiter and record terminator to the ASCII unit separator (\x1F) and record separator (\x1E), respectively.

Example
use std::error::Error;
use futures::stream::StreamExt;
use csv_async::AsyncReaderBuilder;

async fn example() -> Result<(), Box<dyn Error>> {
    let data = "\
city\x1Fcountry\x1Fpop\x1EBoston\x1FUnited States\x1F4628910";
    let mut rdr = AsyncReaderBuilder::new()
        .ascii()
        .create_reader(data.as_bytes());
    let mut records = rdr.byte_records();
    assert_eq!(records.next().await.unwrap()?, vec!["Boston", "United States", "4628910"]);
    assert!(records.next().await.is_none());
    Ok(())
}
source

pub fn buffer_capacity(&mut self, capacity: usize) -> &mut AsyncReaderBuilder

Set the capacity (in bytes) of the buffer used in the CSV reader. This defaults to a reasonable setting.

Trait Implementations§

source§

impl Debug for AsyncReaderBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for AsyncReaderBuilder

source§

fn default() -> AsyncReaderBuilder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more