omni_forge/image_builder/image_gen/
scanner.rs

1#[allow(dead_code)]
2use anyhow::{anyhow, Context, Result};
3use lazy_static::lazy_static;
4use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
5use std::collections::HashMap;
6use std::path::PathBuf;
7use std::{collections::HashSet, fs, path::Path, sync::Mutex};
8use std::{fs::DirEntry, io};
9use thiserror::Error;
10
11lazy_static! {
12    static ref IS_READY: Mutex<bool> = Mutex::new(false);
13    static ref FILETYPES: Mutex<ImageInfo> = Mutex::new(ImageInfo {
14        file_types: HashSet::new(),
15    });
16    static ref FILE_TYPE_LIST: Option<HashMap<String,String>> = {
17        let mut map = HashMap::new();
18
19        // Load the first file
20        if let Ok(json_data) = fs::read_to_string("langs.json").context("Failed to read langs.json") {
21            if let Ok(data) = serde_json5::from_str::<HashMap<String, String>>(&json_data).context("failed to map langs.json into a hashmap") {
22                map.extend(data);
23            }
24        }
25
26        // Load the second file and override values
27        if let Ok(json_data) = fs::read_to_string(".forge_override.json").context("Failed to read override_langs.json") {
28            if let Ok(data) = serde_json5::from_str::<HashMap<String, String>>(&json_data).context("failed to map override_langs.json into a hashmap") {
29                map.extend(data);
30            }
31        }
32
33        Some(map)
34    };
35}
36
37#[derive(Debug)]
38pub struct ImageInfo {
39    pub file_types: HashSet<String>,
40}
41
42#[derive(Debug, Error)]
43#[allow(dead_code)]
44
45enum CompileError {
46    #[error("could not read path: {0}")]
47    InvalidPath(String),
48    #[error("IO error occurred: {0}")]
49    IoError(#[from] io::Error),
50}
51
52pub fn scan(input_path: &str) -> Result<Vec<String>> {
53    let mut _types: HashSet<String> = HashSet::new();
54
55    let path = Path::new(input_path);
56    if path.exists() {
57        _types = get_file_types(path.into())?;
58        let mut type_urls: Vec<String> = Vec::new();
59        for filetype in _types.clone() {
60            if let Some(url) = FILE_TYPE_LIST.as_ref().and_then(|map| map.get(&filetype)) {
61                type_urls.push(url.clone());
62            }
63        }
64        println!("{:?}", type_urls);
65        Ok(type_urls)
66    } else {
67        Err(anyhow!("Path does not exist"))
68    }
69}
70
71fn get_file_types(path: PathBuf) -> Result<HashSet<String>> {
72    let mut file_types = HashSet::new();
73    walk_dir(&path, test_callback).context("failed to walk directory")?;
74    match FILETYPES.lock() {
75        std::result::Result::Ok(types) => {
76            println!("{:#?}", types.file_types);
77            file_types = types.file_types.clone()
78        }
79        Err(e) => {
80            println!("{e}")
81        }
82    }
83    println!("File types collected.");
84    Ok(file_types)
85}
86
87fn walk_dir(input_dir: &PathBuf, callback: fn(&DirEntry)) -> Result<()> {
88    if !input_dir.is_dir() {
89        return Ok(());
90    }
91
92    let entries: Vec<_> = fs::read_dir(input_dir)?
93        .filter_map(|entry| match entry {
94            std::result::Result::Ok(e) => Some(e),
95            Err(err) => {
96                eprintln!("Error reading entry: {}", err);
97                None
98            }
99        })
100        .collect();
101
102    entries
103        .par_iter()
104        .try_for_each::<_, Result<(), anyhow::Error>>(|entry: &DirEntry| {
105            let path = entry.path();
106            if path.is_dir() {
107                if let Err(err) = walk_dir(&path, callback) {
108                    eprintln!("Error walking directory {}: {}", path.display(), err);
109                }
110            } else {
111                callback(entry);
112            }
113            Ok(())
114        })?;
115    Ok(())
116}
117
118fn test_callback(foo: &DirEntry) {
119    if let Some(extension) = foo.path().extension() {
120        if let Some(ext_str) = extension.to_str() {
121            if let std::result::Result::Ok(mut filetypes) = FILETYPES.lock() {
122                filetypes.file_types.insert(ext_str.to_string());
123            } else {
124                eprintln!("Failed to lock FILETYPES mutex.");
125            }
126        }
127    }
128}