hexz_cli/cmd/data/
extract.rs1use anyhow::{Context, Result};
4use hexz_ops::pack::extract_archive;
5use hexz_core::format::header::Header;
6use hexz_core::format::magic::HEADER_SIZE;
7use hexz_store::local::MmapBackend;
8use hexz_store::StorageBackend;
9use std::path::{Path, PathBuf};
10use colored::Colorize;
11
12pub fn run(input: &Path, output: Option<PathBuf>) -> Result<()> {
14 let output = if let Some(p) = output {
16 p
17 } else {
18 let mut out = input.to_path_buf();
20 let _ = out.set_extension("");
21 out
22 };
23
24 let password = {
26 let backend = MmapBackend::new(input)?;
27 let header_bytes = backend.read_exact(0, HEADER_SIZE)?;
28 let header: Header = bincode::deserialize(&header_bytes)?;
29
30 if header.encryption.is_some() {
31 Some(match std::env::var("HEXZ_PASSWORD") {
32 Ok(p) => p,
33 Err(_) => rpassword::prompt_password("Enter decryption password: ")?,
34 })
35 } else {
36 None
37 }
38 };
39
40 println!("{} Extracting {}", "╭".dimmed(), input.display().to_string().cyan());
41 println!("{} Output {}", "╰".dimmed(), output.display().to_string().bright_black());
42
43 extract_archive(input, &output, password).context("Failed to extract archive")?;
44
45 println!("\n {} Extraction complete.", "✓".green());
46
47 Ok(())
48}