pub struct WriterBuilder { /* private fields */ }
Expand description
Builds a CSV writer with various configuration knobs.
This builder can be used to tweak the field delimiter, record terminator
and more. Once a CSV Writer
is built, its configuration cannot be
changed.
Implementations§
Source§impl WriterBuilder
impl WriterBuilder
pub fn build(&self) -> Writer
Sourcepub fn delimiter(&mut self, delimiter: u8) -> &mut WriterBuilder
pub fn delimiter(&mut self, delimiter: u8) -> &mut WriterBuilder
The field delimiter to use when writing CSV.
The default is b','
.
§Example
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.delimiter(b';')
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "b", "c"])?;
wtr.write_record(&mut buf, &["x", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a;b;c\nx;y;z\n");
Ok(())
}
Sourcepub fn has_headers(&mut self, yes: bool) -> &mut WriterBuilder
pub fn has_headers(&mut self, yes: bool) -> &mut WriterBuilder
Whether to write a header row before writing any other row.
When this is enabled and the serialize
method is used to write data
with something that contains field names (i.e., a struct), then a
header row is written containing the field names before any other row
is written.
This option has no effect when using other methods to write rows. That
is, if you don’t use serialize
, then you must write your header row
explicitly if you want a header row.
This is enabled by default.
§Example: with headers
This shows how the header will be automatically written from the field names of a struct.
use std::error::Error;
use csv_stream::WriterBuilder;
use serde::Serialize;
#[derive(Serialize)]
struct Row<'a> {
city: &'a str,
country: &'a str,
// Serde allows us to name our headers exactly,
// even if they don't match our struct field names.
#[serde(rename = "popcount")]
population: u64,
}
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default().build();
let mut buf = vec![];
wtr.serialize(
&mut buf,
Row {
city: "Boston",
country: "United States",
population: 4628910,
},
)?;
wtr.serialize(
&mut buf,
Row {
city: "Concord",
country: "United States",
population: 42695,
},
)?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "\
city,country,popcount
Boston,United States,4628910
Concord,United States,42695
");
Ok(())
}
§Example: without headers
This shows that serializing things that aren’t structs (in this case,
a tuple struct) won’t result in a header row being written. This means
you usually don’t need to set has_headers(false)
unless you
explicitly want to both write custom headers and serialize structs.
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default().build();
let mut buf = vec![];
wtr.serialize(&mut buf, ("Boston", "United States", 4628910))?;
wtr.serialize(&mut buf, ("Concord", "United States", 42695))?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "\
Boston,United States,4628910
Concord,United States,42695
");
Ok(())
}
Sourcepub fn flexible(&mut self, yes: bool) -> &mut WriterBuilder
pub fn flexible(&mut self, yes: bool) -> &mut WriterBuilder
Whether the number of fields in records is allowed to change or not.
When disabled (which is the default), writing CSV data will return an error if a record is written with a number of fields different from the number of fields written in a previous record.
When enabled, this error checking is turned off.
§Example: writing flexible records
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.flexible(true)
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "b"])?;
wtr.write_record(&mut buf, &["x", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a,b\nx,y,z\n");
Ok(())
}
§Example: error when flexible
is disabled
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.flexible(false)
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "b"])?;
let err = wtr.write_record(&mut buf, &["x", "y", "z"]).unwrap_err();
match *err.kind() {
csv_stream::ErrorKind::UnequalLengths { expected_len, len, .. } => {
assert_eq!(expected_len, 2);
assert_eq!(len, 3);
}
ref wrong => {
panic!("expected UnequalLengths but got {:?}", wrong);
}
}
Ok(())
}
Sourcepub fn terminator(&mut self, term: Terminator) -> &mut WriterBuilder
pub fn terminator(&mut self, term: Terminator) -> &mut WriterBuilder
The record terminator to use when writing CSV.
A record terminator can be any single byte. The default is \n
.
Note that RFC 4180 specifies that record terminators should be \r\n
.
To use \r\n
, use the special Terminator::CRLF
value.
§Example: CRLF
This shows how to use RFC 4180 compliant record terminators.
use std::error::Error;
use csv_stream::{Terminator, WriterBuilder};
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.terminator(Terminator::CRLF)
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "b", "c"])?;
wtr.write_record(&mut buf, &["x", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a,b,c\r\nx,y,z\r\n");
Ok(())
}
Sourcepub fn quote_style(&mut self, style: QuoteStyle) -> &mut WriterBuilder
pub fn quote_style(&mut self, style: QuoteStyle) -> &mut WriterBuilder
The quoting style to use when writing CSV.
By default, this is set to QuoteStyle::Necessary
, which will only
use quotes when they are necessary to preserve the integrity of data.
Note that unless the quote style is set to Never
, an empty field is
quoted if it is the only field in a record.
§Example: non-numeric quoting
This shows how to quote non-numeric fields only.
use std::error::Error;
use csv_stream::{QuoteStyle, WriterBuilder};
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.quote_style(QuoteStyle::NonNumeric)
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "5", "c"])?;
wtr.write_record(&mut buf, &["3.14", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "\"a\",5,\"c\"\n3.14,\"y\",\"z\"\n");
Ok(())
}
§Example: never quote
This shows how the CSV writer can be made to never write quotes, even if it sacrifices the integrity of the data.
use std::error::Error;
use csv_stream::{QuoteStyle, WriterBuilder};
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.quote_style(QuoteStyle::Never)
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "foo\nbar", "c"])?;
wtr.write_record(&mut buf, &["g\"h\"i", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a,foo\nbar,c\ng\"h\"i,y,z\n");
Ok(())
}
Sourcepub fn quote(&mut self, quote: u8) -> &mut WriterBuilder
pub fn quote(&mut self, quote: u8) -> &mut WriterBuilder
The quote character to use when writing CSV.
The default is b'"'
.
§Example
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.quote(b'\'')
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "foo\nbar", "c"])?;
wtr.write_record(&mut buf, &["g'h'i", "y\"y\"y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a,'foo\nbar',c\n'g''h''i',y\"y\"y,z\n");
Ok(())
}
Sourcepub fn double_quote(&mut self, yes: bool) -> &mut WriterBuilder
pub fn double_quote(&mut self, yes: bool) -> &mut WriterBuilder
Enable double quote escapes.
This is enabled by default, but it may be disabled. When disabled, quotes in field data are escaped instead of doubled.
§Example
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.double_quote(false)
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "foo\"bar", "c"])?;
wtr.write_record(&mut buf, &["x", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a,\"foo\\\"bar\",c\nx,y,z\n");
Ok(())
}
Sourcepub fn escape(&mut self, escape: u8) -> &mut WriterBuilder
pub fn escape(&mut self, escape: u8) -> &mut WriterBuilder
The escape character to use when writing CSV.
In some variants of CSV, quotes are escaped using a special escape
character like \
(instead of escaping quotes by doubling them).
By default, writing these idiosyncratic escapes is disabled, and is
only used when double_quote
is disabled.
§Example
use std::error::Error;
use csv_stream::WriterBuilder;
fn example() -> Result<(), Box<dyn Error>> {
let mut wtr = WriterBuilder::default()
.double_quote(false)
.escape(b'$')
.build();
let mut buf = vec![];
wtr.write_record(&mut buf, &["a", "foo\"bar", "c"])?;
wtr.write_record(&mut buf, &["x", "y", "z"])?;
let data = String::from_utf8(buf)?;
assert_eq!(data, "a,\"foo$\"bar\",c\nx,y,z\n");
Ok(())
}
Sourcepub fn build_iter<I: IntoIterator>(&self, iter: I) -> Iter<I::IntoIter> ⓘ
pub fn build_iter<I: IntoIterator>(&self, iter: I) -> Iter<I::IntoIter> ⓘ
Create a new iterator for creating CSVs from the given iterator of rows
§Example
use std::error::Error;
use csv_stream::WriterBuilder;
use serde::Serialize;
fn example() -> Result<(), Box<dyn Error>> {
#[derive(Serialize)]
struct Row { foo: usize, bar: usize }
let rows = [
Row{ foo: 1, bar: 2 },
Row{ foo: 3, bar: 4 },
];
let mut csv_iter = WriterBuilder::default().build_iter(rows);
let mut buf = vec![];
for row in csv_iter {
let row = row.unwrap();
buf.extend_from_slice(&row);
}
let data = String::from_utf8(buf)?;
assert_eq!(data, "foo,bar\n1,2\n3,4\n");
Ok(())
}
Sourcepub fn build_stream<S>(&self, stream: S) -> Stream<S>
pub fn build_stream<S>(&self, stream: S) -> Stream<S>
Create a new stream for creating CSVs from the given stream of rows
§Example
use std::error::Error;
use csv_stream::WriterBuilder;
use serde::Serialize;
use futures::StreamExt;
async fn example() -> Result<(), Box<dyn Error>> {
#[derive(Serialize)]
struct Row { foo: usize, bar: usize }
let rows = [
Row{ foo: 1, bar: 2 },
Row{ foo: 3, bar: 4 },
];
// a Stream over rows
let stream = futures::stream::iter(rows);
let mut csv_stream = WriterBuilder::default().build_stream(stream);
let mut buf = vec![];
while let Some(row) = csv_stream.next().await {
let row = row.unwrap();
buf.extend_from_slice(&row);
}
let data = String::from_utf8(buf)?;
assert_eq!(data, "foo,bar\n1,2\n3,4\n");
Ok(())
}