poe_data_tools_cli/commands/
extract.rs1use std::{
2 fs::{self},
3 path::Path,
4};
5
6use anyhow::{Context, Result};
7use glob::{MatchOptions, Pattern};
8use poe_data_tools::fs::{FS, FileSystem};
9
10pub fn extract_files(fs: &mut FS, patterns: &[Pattern], output_folder: &Path) -> Result<()> {
12 let filenames = fs
13 .list()
14 .filter(|filename| {
15 patterns.iter().any(|pattern| {
16 pattern.matches_with(
17 filename,
18 MatchOptions {
19 require_literal_separator: true,
20 ..Default::default()
21 },
22 )
23 })
24 })
25 .collect::<Vec<_>>();
26
27 fs.batch_read(&filenames)
28 .filter_map(|(path, res)| match res {
30 Ok(b) => Some((path, b)),
31 Err(e) => {
32 log::error!("Failed to extract file: {:?}: {:?}", path, e);
33 None
34 }
35 })
36 .map(|(filename, contents)| -> Result<_, anyhow::Error> {
38 let out_filename = output_folder.join(filename.as_ref());
39 fs::create_dir_all(out_filename.parent().unwrap()).with_context(|| {
40 format!(
41 "Failed to create folder: {:?}",
42 out_filename.parent().unwrap()
43 )
44 })?;
45
46 fs::write(&out_filename, &contents)
47 .with_context(|| format!("Failed to write file: {:?}", out_filename))?;
48
49 Ok(filename)
50 })
51 .for_each(|result| match result {
53 Ok(filename) => log::info!("Extracted file: {}", filename),
54 Err(e) => log::error!("Failed to extract file: {:?}", e),
55 });
56
57 Ok(())
58}