1use super::*;
4use car_util::DirectoryItem;
5use std::cell::RefCell;
6use std::fs::File;
7use std::io;
8use std::rc::Rc;
9
10pub struct Dir<W: io::Write> {
11 curr_file_id: Rc<RefCell<u64>>,
12 next_writer: W,
13}
14
15impl<W: io::Write> Dir<W> {
16 pub fn new(curr_file_id: Rc<RefCell<u64>>, next_writer: W) -> Self {
17 Dir {
18 curr_file_id,
19 next_writer,
20 }
21 }
22
23 pub fn walk_write(&mut self, dir_items: &[DirectoryItem]) -> io::Result<()> {
24 for item in dir_items {
25 match item {
26 DirectoryItem::File(_, path, id) => {
27 *self.curr_file_id.borrow_mut() = *id;
28 let mut file = File::open(path)?;
29 io::copy(&mut file, &mut self.next_writer)?;
30 self.next_writer.flush()?;
31 }
32 DirectoryItem::Directory(_, sub_dir_items) => {
33 self.walk_write(sub_dir_items)?;
34 }
35 }
36 }
37
38 Ok(())
39 }
40
41 #[cfg(feature = "zstd")]
42 pub fn walk_write_with_compression(
43 &mut self,
44 dir_items: &[DirectoryItem],
45 level: Option<i32>,
46 ) -> io::Result<()> {
47 for item in dir_items {
48 match item {
49 DirectoryItem::File(_, path, id) => {
50 *self.curr_file_id.borrow_mut() = *id;
51 let mut file = File::open(path)?;
52
53 let mut compressor =
54 zstd::stream::Encoder::new(&mut self.next_writer, level.unwrap_or(10))?;
55 io::copy(&mut file, &mut compressor)?;
56
57 compressor.finish()?;
58 self.next_writer.flush()?;
59 }
60 DirectoryItem::Directory(_, sub_dir_items) => {
61 self.walk_write_with_compression(sub_dir_items, level)?;
62 }
63 }
64 }
65
66 Ok(())
67 }
68
69 pub fn next(self) -> W {
70 self.next_writer
71 }
72}