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 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
24 let path = path.as_ref().to_path_buf();
25 Ok(Self {
26 path,
27 config: SecurityConfig::default(),
28 })
29 }
30
31 #[must_use]
33 pub fn path(&self) -> &Path {
34 &self.path
35 }
36
37 #[must_use]
39 pub fn config(&self) -> &SecurityConfig {
40 &self.config
41 }
42
43 pub fn extract<P: AsRef<Path>>(&self, output_dir: P) -> Result<ExtractionReport> {
49 crate::api::extract_archive(&self.path, output_dir.as_ref(), &self.config)
50 }
51}
52
53#[derive(Debug, Default)]
71pub struct ArchiveBuilder {
72 archive_path: Option<PathBuf>,
73 output_dir: Option<PathBuf>,
74 config: Option<SecurityConfig>,
75}
76
77impl ArchiveBuilder {
78 #[must_use]
80 pub fn new() -> Self {
81 Self::default()
82 }
83
84 #[must_use]
86 pub fn archive<P: AsRef<Path>>(mut self, path: P) -> Self {
87 self.archive_path = Some(path.as_ref().to_path_buf());
88 self
89 }
90
91 #[must_use]
93 pub fn output_dir<P: AsRef<Path>>(mut self, path: P) -> Self {
94 self.output_dir = Some(path.as_ref().to_path_buf());
95 self
96 }
97
98 #[must_use]
100 pub fn config(mut self, config: SecurityConfig) -> Self {
101 self.config = Some(config);
102 self
103 }
104
105 pub fn extract(self) -> Result<ExtractionReport> {
112 let archive_path =
113 self.archive_path
114 .ok_or_else(|| crate::ExtractionError::SecurityViolation {
115 reason: "archive path not set".to_string(),
116 })?;
117
118 let output_dir =
119 self.output_dir
120 .ok_or_else(|| crate::ExtractionError::SecurityViolation {
121 reason: "output directory not set".to_string(),
122 })?;
123
124 let config = self.config.unwrap_or_default();
125
126 crate::api::extract_archive(archive_path, output_dir, &config)
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn test_archive_builder() {
136 let builder = ArchiveBuilder::new()
137 .archive("test.tar")
138 .output_dir("/tmp/test");
139
140 assert!(builder.archive_path.is_some());
141 assert!(builder.output_dir.is_some());
142 }
143
144 #[test]
145 fn test_archive_builder_missing_path() {
146 let builder = ArchiveBuilder::new().output_dir("/tmp/test");
147 let result = builder.extract();
148 assert!(result.is_err());
149 }
150
151 #[test]
152 fn test_archive_builder_missing_output() {
153 let builder = ArchiveBuilder::new().archive("test.tar");
154 let result = builder.extract();
155 assert!(result.is_err());
156 }
157}