1use {
2 super::{error::Error, header::CarHeader, util::write_varint_usize},
3 crate::cid::Cid,
4 alloc::vec::Vec,
5 core2::io::Write,
6};
7
8#[derive(Debug)]
9pub struct CarWriter<W> {
10 header: CarHeader,
11 writer: W,
12 cid_buffer: Vec<u8>,
13 is_header_written: bool,
14}
15
16impl<W> CarWriter<W>
17where
18 W: Write + Send + Unpin,
19{
20 pub fn new(header: CarHeader, writer: W) -> Self {
21 CarWriter {
22 header,
23 writer,
24 cid_buffer: Vec::new(),
25 is_header_written: false,
26 }
27 }
28
29 pub fn write_header(&mut self) -> Result<usize, Error> {
33 let mut written = 0;
34
35 if !self.is_header_written {
36 let header_bytes = self.header.encode()?;
38 written += write_varint_usize(header_bytes.len(), &mut self.writer)?;
39 self.writer.write_all(&header_bytes)?;
40 written += header_bytes.len();
41 self.is_header_written = true;
42 }
43
44 Ok(written)
45 }
46
47 pub fn write<T>(&mut self, cid: Cid, data: T) -> Result<usize, Error>
51 where
52 T: AsRef<[u8]>,
53 {
54 let mut written = 0;
55 written += self.write_header()?;
56
57 self.cid_buffer.clear();
59 cid.write_bytes(&mut self.cid_buffer).expect("vec write");
60
61 let data = data.as_ref();
62 let len = self.cid_buffer.len() + data.len();
63
64 written += write_varint_usize(len, &mut self.writer)?;
65 self.writer.write_all(&self.cid_buffer)?;
66 self.writer.write_all(data)?;
67 written += self.cid_buffer.len();
68 written += data.len();
69
70 Ok(written)
71 }
72
73 pub fn finish(mut self) -> Result<W, Error> {
75 self.flush()?;
76 Ok(self.writer)
77 }
78
79 pub fn flush(&mut self) -> Result<(), Error> {
81 self.writer.flush()?;
82 Ok(())
83 }
84
85 pub fn into_inner(self) -> W {
87 self.writer
88 }
89}