Skip to main content

poe_data_tools_cli/commands/
translate.rs

1use std::path::Path;
2
3use anyhow::{Context, Result};
4use glob::{MatchOptions, Pattern};
5use poe_data_tools::{
6    Patch,
7    file_parsers::{FileParserExt, Parser},
8    fs::{FS, FileSystem},
9};
10
11/// Extract, parse and transform files into easier to parse alternatives
12pub fn translate(
13    fs: &mut FS,
14    patterns: &[Pattern],
15    _cache_dir: &Path,
16    output_folder: &Path,
17    poe_version: &Patch,
18) -> Result<()> {
19    let filenames = fs
20        .list()
21        // Filter on globs
22        .filter(|filename| {
23            patterns.iter().any(|pattern| {
24                pattern.matches_with(
25                    filename,
26                    MatchOptions {
27                        require_literal_separator: true,
28                        ..Default::default()
29                    },
30                )
31            })
32        })
33        // Filter out files that we can't parse
34        // TODO: This might be expensive, also we might want to log skips?
35        .filter(|filename| {
36            Parser::from_filename(Path::new(filename), poe_version.major()).is_some()
37        })
38        .collect::<Vec<_>>();
39
40    fs.batch_read(&filenames)
41        // Print and filter out errors
42        .filter_map(|(path, res)| match res {
43            Ok(b) => Some((path, b)),
44            Err(e) => {
45                log::error!("Failed to extract file: {:?}: {:?}", path, e);
46                None
47            }
48        })
49        // Attempt to read file contents
50        .map(|(filename, contents)| -> Result<_, anyhow::Error> {
51            log::info!("Extracting file: {filename}");
52            let parser = Parser::from_filename(Path::new(filename.as_ref()), poe_version.major())
53                .expect("Already verified parser exists above");
54
55            let out_path = output_folder
56                .join(filename.as_ref())
57                .with_added_extension("json");
58            parser
59                .parse_to_json_file(&contents, &out_path)
60                .with_context(|| format!("Failed to process file: {:?}", filename))?;
61
62            Ok(filename)
63        })
64        // Report results
65        .for_each(|result| match result {
66            Ok(filename) => log::info!("Extracted file: {}", filename),
67            Err(e) => log::error!("{:?}", e),
68        });
69
70    Ok(())
71}