flams_system/backend/archives/
ignore_regex.rs

1use flams_utils::regex::Regex;
2use std::fmt::Display;
3use std::path::Path;
4#[cfg(target_os = "windows")]
5const PATH_SEPARATOR: &str = "\\\\";
6#[cfg(not(target_os = "windows"))]
7const PATH_SEPARATOR: char = '/';
8
9#[derive(Default, Clone, Debug)]
10pub struct IgnoreSource(Option<Regex>);
11impl Display for IgnoreSource {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        match &self.0 {
14            Some(r) => Display::fmt(r, f),
15            None => write!(f, "(None)"),
16        }
17    }
18}
19
20impl PartialEq for IgnoreSource {
21    fn eq(&self, other: &Self) -> bool {
22        match (&self.0, &other.0) {
23            (Some(a), Some(b)) => a.as_str() == b.as_str(),
24            (None, None) => true,
25            _ => false,
26        }
27    }
28}
29
30impl IgnoreSource {
31    pub fn new(regex: &str, source_path: &Path) -> Self {
32        if regex.is_empty() {
33            return Self::default();
34        }
35        #[cfg(target_os = "windows")]
36        let regex = regex.replace('/', PATH_SEPARATOR);
37        let s = regex.replace('.', r"\.").replace('*', ".*"); //.replace('/',r"\/");
38        let s = s
39            .split('|')
40            .filter(|s| !s.is_empty())
41            .collect::<Vec<_>>()
42            .join("|");
43        let p = source_path.display(); //path.to_str().unwrap().replace('/',r"\/");
44        #[cfg(target_os = "windows")]
45        let p = p.to_string().replace('\\', PATH_SEPARATOR);
46        let s = format!("{p}({PATH_SEPARATOR})?({s})");
47        Self(Regex::new(&s).ok())
48    }
49    pub fn ignores(&self, p: &Path) -> bool {
50        let Some(p) = p.to_str() else { return false };
51        self.0.as_ref().is_some_and(|r| r.is_match(p))
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    fn get_ignore(source: &Path) -> IgnoreSource {
59        IgnoreSource::new("*/code/*|*/tikz/*|*/tutorial/solution/*", source)
60    }
61
62    #[test]
63    fn ignore_test() {
64        #[cfg(target_os = "windows")]
65        let source = Path::new("C:\\home\\jazzpirate\\work\\MathHub\\sTeX\\Documentation\\source");
66        #[cfg(not(target_os = "windows"))]
67        let source = Path::new("/home/jazzpirate/work/MathHub/sTeX/Documentation/source");
68        let ignore = get_ignore(source);
69
70        #[cfg(target_os = "windows")]
71        let path = Path::new("C:\\home\\jazzpirate\\work\\MathHub\\sTeX\\Documentation\\source\\tutorial\\solution\\preamble.tex");
72        #[cfg(not(target_os = "windows"))]
73        let path = Path::new("/home/jazzpirate/work/MathHub/sTeX/Documentation/source/tutorial/solution/preamble.tex");
74        assert!(ignore.ignores(path));
75
76        #[cfg(target_os = "windows")]
77        let path = Path::new("C:\\home\\jazzpirate\\work\\MathHub\\sTeX\\Documentation\\source\\tutorial\\math\\assertions.en.tex");
78        #[cfg(not(target_os = "windows"))]
79        let path = Path::new("/home/jazzpirate/work/MathHub/sTeX/Documentation/source/tutorial/math/assertions.en.tex");
80        assert!(!ignore.ignores(path));
81    }
82}