trillium_include_dir/
dir.rs1use crate::file::File;
2use std::fs;
3use std::io::Write;
4use std::path::Path;
5use std::time::{Duration, SystemTime, UNIX_EPOCH};
6
7#[derive(Debug, Copy, Clone, PartialEq)]
9pub struct Dir<'a> {
10 #[doc(hidden)]
11 pub path: &'a str,
12
13 #[doc(hidden)]
14 pub files: &'a [File<'a>],
15
16 #[doc(hidden)]
17 pub dirs: &'a [Dir<'a>],
18
19 #[doc(hidden)]
20 pub modified: Option<f64>,
21
22 #[doc(hidden)]
23 pub created: Option<f64>,
24
25 #[doc(hidden)]
26 pub accessed: Option<f64>,
27}
28
29impl<'a> Dir<'a> {
30 pub fn path(&self) -> &'a Path {
32 Path::new(self.path)
33 }
34
35 pub fn files(&self) -> &'a [File<'a>] {
37 self.files
38 }
39
40 pub fn dirs(&self) -> &'a [Dir<'a>] {
42 self.dirs
43 }
44
45 pub fn contains<S: AsRef<Path>>(&self, path: S) -> bool {
47 let path = path.as_ref();
48
49 self.get_file(path).is_some() || self.get_dir(path).is_some()
50 }
51
52 pub fn get_dir<S: AsRef<Path>>(&self, path: S) -> Option<Dir<'a>> {
55 let path = path.as_ref();
56
57 for dir in self.dirs {
58 if Path::new(dir.path) == path {
59 return Some(*dir);
60 }
61
62 if let Some(d) = dir.get_dir(path) {
63 return Some(d);
64 }
65 }
66
67 None
68 }
69
70 pub fn get_file<S: AsRef<Path>>(&self, path: S) -> Option<File<'a>> {
73 let path = path.as_ref();
74
75 for file in self.files {
76 if Path::new(file.path) == path {
77 return Some(*file);
78 }
79 }
80
81 for dir in self.dirs {
82 if let Some(d) = dir.get_file(path) {
83 return Some(d);
84 }
85 }
86
87 None
88 }
89
90 pub fn extract<S: AsRef<Path>>(&self, path: S) -> std::io::Result<()> {
95 fn extract_dir<S: AsRef<Path>>(dir: Dir<'_>, path: S) -> std::io::Result<()> {
98 let path = path.as_ref();
99 for dir in dir.dirs() {
101 fs::create_dir_all(path.join(dir.path()))?;
102 extract_dir(*dir, path)?;
103 }
104
105 for file in dir.files() {
107 let mut fsf = fs::OpenOptions::new()
108 .write(true)
109 .create_new(true)
110 .open(path.join(file.path()))?;
111 fsf.write_all(file.contents())?;
112 fsf.sync_all()?;
113 }
114
115 Ok(())
116 }
117
118 extract_dir(*self, path)
119 }
120
121 pub fn created(&self) -> Option<SystemTime> {
124 self.created
125 .map(|secs| UNIX_EPOCH + Duration::from_secs_f64(secs))
126 }
127
128 pub fn modified(&self) -> Option<SystemTime> {
131 self.modified
132 .map(|secs| UNIX_EPOCH + Duration::from_secs_f64(secs))
133 }
134
135 pub fn accessed(&self) -> Option<SystemTime> {
138 self.accessed
139 .map(|secs| UNIX_EPOCH + Duration::from_secs_f64(secs))
140 }
141}