rama_utils/include_dir/
dir.rs1use super::{DirEntry, File};
2use crate::fs::{safe_create_dir_all_in_sync, safe_write_in_sync};
3use std::path::Path;
4
5#[derive(Debug, Clone, PartialEq)]
7pub struct Dir<'a> {
8 path: &'a str,
9 entries: &'a [DirEntry<'a>],
10}
11
12impl<'a> Dir<'a> {
13 #[must_use]
15 pub const fn new(path: &'a str, entries: &'a [DirEntry<'a>]) -> Self {
16 Dir { path, entries }
17 }
18
19 #[must_use]
22 pub fn path(&self) -> &'a Path {
23 Path::new(self.path)
24 }
25
26 #[must_use]
28 pub const fn entries(&self) -> &'a [DirEntry<'a>] {
29 self.entries
30 }
31
32 pub fn files(&self) -> impl Iterator<Item = &'a File<'a>> + 'a {
34 self.entries().iter().filter_map(DirEntry::as_file)
35 }
36
37 pub fn dirs(&self) -> impl Iterator<Item = &'a Dir<'a>> + 'a {
39 self.entries().iter().filter_map(DirEntry::as_dir)
40 }
41
42 pub fn get_entry<S: AsRef<Path>>(&self, path: S) -> Option<&'a DirEntry<'a>> {
44 let path = path.as_ref();
45
46 for entry in self.entries() {
47 if entry.path() == path {
48 return Some(entry);
49 }
50
51 if let DirEntry::Dir(d) = entry
52 && let Some(nested) = d.get_entry(path)
53 {
54 return Some(nested);
55 }
56 }
57
58 None
59 }
60
61 pub fn get_file<S: AsRef<Path>>(&self, path: S) -> Option<&'a File<'a>> {
63 self.get_entry(path).and_then(DirEntry::as_file)
64 }
65
66 pub fn get_dir<S: AsRef<Path>>(&self, path: S) -> Option<&'a Self> {
68 self.get_entry(path).and_then(DirEntry::as_dir)
69 }
70
71 pub fn contains<S: AsRef<Path>>(&self, path: S) -> bool {
73 self.get_entry(path).is_some()
74 }
75
76 pub fn extract<S: AsRef<Path>>(&self, base_path: S) -> std::io::Result<()> {
87 let base_path = base_path.as_ref();
88 std::fs::create_dir_all(base_path)?;
89 self.extract_entries(base_path)
90 }
91
92 fn extract_entries(&self, base_path: &Path) -> std::io::Result<()> {
93 for entry in self.entries() {
94 match entry {
95 DirEntry::Dir(d) => {
96 safe_create_dir_all_in_sync(base_path, d.path())?;
97 d.extract_entries(base_path)?;
98 }
99 DirEntry::File(f) => {
100 safe_write_in_sync(base_path, f.path(), f.contents())?;
101 }
102 }
103 }
104
105 Ok(())
106 }
107}