use std::io::prelude::*;
use std::marker::PhantomData;
use std::mem::drop;
use anyhow::Result;
use csv;
use serde::Serialize;
mod chunks;
mod thread;
mod transform;
pub use chunks::{ChunkWriter, UnchunkWriter};
pub use thread::ThreadObjectWriter;
pub use transform::MapWriter;
pub trait ObjectWriter<T>: Sized {
fn write_object(&mut self, object: T) -> Result<()>;
fn write_all_objects<I>(&mut self, objects: I) -> Result<usize>
where
I: Iterator<Item = T>,
{
let mut count = 0;
for obj in objects {
self.write_object(obj)?;
count += 1;
}
Ok(count)
}
fn write_and_finish<I>(mut self, objects: I) -> Result<usize>
where
I: Iterator<Item = T>,
{
let n = self.write_all_objects(objects)?;
self.finish()?;
Ok(n)
}
fn finish(self) -> Result<usize>;
fn with_transform<F, T2>(self, transform: F) -> MapWriter<F, T2, T, Self>
where
F: Fn(T2) -> Result<T>,
{
MapWriter {
_phantom: PhantomData,
transform,
writer: self,
}
}
}
impl<T, W> ObjectWriter<T> for &mut W
where
W: ObjectWriter<T>,
{
fn write_object(&mut self, object: T) -> Result<()> {
(**self).write_object(object)
}
fn finish(self) -> Result<usize> {
Ok(0)
}
}
impl<T: Serialize, W: Write> ObjectWriter<T> for csv::Writer<W> {
fn write_object(&mut self, object: T) -> Result<()> {
self.serialize(object)?;
Ok(())
}
fn finish(mut self) -> Result<usize> {
self.flush()?;
drop(self);
Ok(0)
}
}