use alloc::string::String;
#[derive(Debug, Clone, Default)]
pub struct CsvWriter {
out: String,
}
impl CsvWriter {
pub const fn new() -> Self {
Self { out: String::new() }
}
pub fn write_record<I, S>(&mut self, fields: I)
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
let mut first = true;
for field in fields {
if !first {
self.out.push(',');
}
first = false;
write_field(&mut self.out, field.as_ref());
}
self.out.push_str("\r\n");
}
pub fn len(&self) -> usize {
self.out.len()
}
pub fn is_empty(&self) -> bool {
self.out.is_empty()
}
pub fn as_str(&self) -> &str {
&self.out
}
pub fn into_string(self) -> String {
self.out
}
}
fn write_field(out: &mut String, field: &str) {
if needs_quoting(field) {
out.push('"');
for c in field.chars() {
if c == '"' {
out.push('"');
}
out.push(c);
}
out.push('"');
} else {
out.push_str(field);
}
}
fn needs_quoting(field: &str) -> bool {
field
.bytes()
.any(|b| matches!(b, b',' | b'"' | b'\r' | b'\n'))
}