1use std::path::Path;
4use std::path::PathBuf;
5
6use crate::ExtractionReport;
7use crate::Result;
8use crate::SecurityConfig;
9
10#[derive(Debug)]
12pub struct Archive {
13 path: PathBuf,
14 config: SecurityConfig,
15}
16
17impl Archive {
18 #[must_use]
31 pub fn open<P: AsRef<Path>>(path: P) -> Self {
32 let path = path.as_ref().to_path_buf();
33 Self {
34 path,
35 config: SecurityConfig::default(),
36 }
37 }
38
39 #[must_use]
41 pub fn path(&self) -> &Path {
42 &self.path
43 }
44
45 #[must_use]
47 pub fn config(&self) -> &SecurityConfig {
48 &self.config
49 }
50
51 pub fn extract<P: AsRef<Path>>(&self, output_dir: P) -> Result<ExtractionReport> {
57 crate::api::extract_archive(&self.path, output_dir.as_ref(), &self.config)
58 }
59}
60
61#[derive(Debug, Default)]
79pub struct ArchiveBuilder {
80 archive_path: Option<PathBuf>,
81 output_dir: Option<PathBuf>,
82 config: Option<SecurityConfig>,
83}
84
85impl ArchiveBuilder {
86 #[must_use]
88 pub fn new() -> Self {
89 Self::default()
90 }
91
92 #[must_use]
94 pub fn archive<P: AsRef<Path>>(mut self, path: P) -> Self {
95 self.archive_path = Some(path.as_ref().to_path_buf());
96 self
97 }
98
99 #[must_use]
101 pub fn output_dir<P: AsRef<Path>>(mut self, path: P) -> Self {
102 self.output_dir = Some(path.as_ref().to_path_buf());
103 self
104 }
105
106 #[must_use]
108 pub fn config(mut self, config: SecurityConfig) -> Self {
109 self.config = Some(config);
110 self
111 }
112
113 pub fn extract(self) -> Result<ExtractionReport> {
120 let archive_path =
121 self.archive_path
122 .ok_or_else(|| crate::ArchiveError::InvalidConfiguration {
123 reason: "archive path not set".to_string(),
124 })?;
125
126 let output_dir =
127 self.output_dir
128 .ok_or_else(|| crate::ArchiveError::InvalidConfiguration {
129 reason: "output directory not set".to_string(),
130 })?;
131
132 let config = self.config.unwrap_or_default();
133
134 crate::api::extract_archive(archive_path, output_dir, &config)
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141 use std::assert_matches;
142
143 #[test]
144 fn test_archive_builder() {
145 let builder = ArchiveBuilder::new()
146 .archive("test.tar")
147 .output_dir("/tmp/test");
148
149 assert!(builder.archive_path.is_some());
150 assert!(builder.output_dir.is_some());
151 }
152
153 #[test]
154 fn test_archive_builder_missing_path() {
155 let builder = ArchiveBuilder::new().output_dir("/tmp/test");
156 let result = builder.extract();
157 assert_matches!(
158 result,
159 Err(crate::ArchiveError::InvalidConfiguration { .. })
160 );
161 }
162
163 #[test]
164 fn test_archive_builder_missing_output() {
165 let builder = ArchiveBuilder::new().archive("test.tar");
166 let result = builder.extract();
167 assert_matches!(
168 result,
169 Err(crate::ArchiveError::InvalidConfiguration { .. })
170 );
171 }
172}