bookdata/io/object/
mod.rs

1use std::io::prelude::*;
2use std::marker::PhantomData;
3use std::mem::drop;
4
5use anyhow::Result;
6use csv;
7use serde::Serialize;
8
9mod chunks;
10mod thread;
11mod transform;
12
13pub use chunks::{ChunkWriter, UnchunkWriter};
14pub use thread::ThreadObjectWriter;
15pub use transform::MapWriter;
16
17/// Trait for writing objects to some kind of sink.
18pub trait ObjectWriter<T>: Sized {
19    /// Write one object.
20    fn write_object(&mut self, object: T) -> Result<()>;
21
22    /// Write an iterator full of objects.
23    fn write_all_objects<I>(&mut self, objects: I) -> Result<usize>
24    where
25        I: Iterator<Item = T>,
26    {
27        let mut count = 0;
28        for obj in objects {
29            self.write_object(obj)?;
30            count += 1;
31        }
32        Ok(count)
33    }
34
35    /// Write an iterator of objects and finish the writer.
36    fn write_and_finish<I>(mut self, objects: I) -> Result<usize>
37    where
38        I: Iterator<Item = T>,
39    {
40        let n = self.write_all_objects(objects)?;
41        self.finish()?;
42        Ok(n)
43    }
44
45    /// Finish and close the target.
46    fn finish(self) -> Result<usize>;
47
48    /// Wrap this object writer in a transformed writer.
49    fn with_transform<F, T2>(self, transform: F) -> MapWriter<F, T2, T, Self>
50    where
51        F: Fn(T2) -> Result<T>,
52    {
53        MapWriter {
54            _phantom: PhantomData,
55            transform,
56            writer: self,
57        }
58    }
59}
60
61/// References can be used as object writers; however, [ObjectWriter::finish] must
62/// be called on the owned writer, not a reference.  Closing the reference is a
63/// no-op.
64impl<T, W> ObjectWriter<T> for &mut W
65where
66    W: ObjectWriter<T>,
67{
68    fn write_object(&mut self, object: T) -> Result<()> {
69        (**self).write_object(object)
70    }
71
72    fn finish(self) -> Result<usize> {
73        // closing a reference does *not* close the write
74        Ok(0)
75    }
76}
77
78impl<T: Serialize, W: Write> ObjectWriter<T> for csv::Writer<W> {
79    fn write_object(&mut self, object: T) -> Result<()> {
80        self.serialize(object)?;
81        Ok(())
82    }
83
84    fn finish(mut self) -> Result<usize> {
85        self.flush()?;
86        drop(self);
87        Ok(0)
88    }
89}