Skip to main content

supreme_cleaner/
txt_processor.rs

1use std::io;
2use std::path::Path;
3
4use supreme_fs::GameStorage;
5
6/// Process a .txt file line by line, allowing transformation of quoted paths.
7///
8/// The `path_transformer` function receives:
9/// - `value_str`: The extracted quoted value from a line
10/// - `line`: The full original line
11///
12/// It should return `Some(new_line)` if the line should be modified, or `None` to keep the original.
13///
14/// Returns `Ok(true)` if the file was modified, `Ok(false)` if not modified.
15/// Handles decoding/encoding automatically using Windows-1252.
16pub fn process_txt_file<F>(
17    storage: &GameStorage,
18    txt_file: &Path,
19    mut path_transformer: F,
20) -> io::Result<bool>
21where
22    F: FnMut(&str) -> Option<String>,
23{
24    // Read with correct encoding using GameStorage
25    let content = match storage.read_text(txt_file) {
26        Ok(c) => c,
27        Err(_) => return Ok(false),
28    };
29
30    let mut new_content = String::with_capacity(content.len());
31    let mut modified = false;
32
33    for line in content.lines() {
34        let mut new_line = String::new();
35        let mut last_pos = 0;
36        let mut search_pos = 0;
37
38        // Find all occurrences of = "..." in the line
39        while let Some(eq_pos) = line[search_pos..].find('=') {
40            let abs_eq = search_pos + eq_pos;
41
42            // Look for next quote after '='
43            if let Some(start_quote) = line[abs_eq + 1..].find('"') {
44                let abs_start = abs_eq + 1 + start_quote;
45
46                if let Some(end_quote) = line[abs_start + 1..].find('"') {
47                    let abs_end = abs_start + 1 + end_quote;
48                    let value = &line[abs_start + 1..abs_end];
49
50                    // Push everything from last_pos up to the start of the value
51                    new_line.push_str(&line[last_pos..=abs_start]);
52
53                    // Try to transform the value
54                    if let Some(transformed) = path_transformer(value) {
55                        new_line.push_str(&transformed);
56                        modified = true;
57                    } else {
58                        new_line.push_str(value);
59                    }
60
61                    // Push closing quote
62                    new_line.push('"');
63
64                    last_pos = abs_end + 1;
65                    search_pos = abs_end + 1;
66                } else {
67                    // Unclosed quote, skip this '='
68                    search_pos = abs_eq + 1;
69                }
70            } else {
71                // No quote after '=', skip this '='
72                search_pos = abs_eq + 1;
73            }
74        }
75
76        // Push remaining part of the line
77        new_line.push_str(&line[last_pos..]);
78        new_content.push_str(&new_line);
79        new_content.push('\n');
80    }
81
82    if modified {
83        storage.write_text(txt_file, &new_content)?;
84    }
85
86    Ok(modified)
87}