flams_math_archives/utils/
ignore_source.rs1use regex::Regex;
2use std::path::{Path, PathBuf};
3
4use crate::utils::path_ext::PathExt;
5
6#[derive(Default, Clone, Debug)]
22pub struct IgnoreSource(Option<Regex>);
23impl std::fmt::Display for IgnoreSource {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 match &self.0 {
26 Some(r) => r.fmt(f),
27 None => write!(f, "(None)"),
28 }
29 }
30}
31
32impl PartialEq for IgnoreSource {
33 fn eq(&self, other: &Self) -> bool {
34 match (&self.0, &other.0) {
35 (Some(a), Some(b)) => a.as_str() == b.as_str(),
36 (None, None) => true,
37 _ => false,
38 }
39 }
40}
41
42impl IgnoreSource {
43 #[must_use]
44 pub fn new(regex: &str, source_path: &Path) -> Self {
45 if regex.is_empty() {
46 return Self::default();
47 }
48 let s = regex.replace('.', r"\.").replace('*', ".*");
51 let s = s
52 .split('|')
53 .filter(|s| !s.is_empty())
54 .collect::<Vec<_>>()
55 .join("|");
56 let p = source_path.display();
57 #[cfg(target_os = "windows")]
58 let p = p.to_string()[3..].replace(PathBuf::PATH_SEPARATOR,"/");
59 let s = format!("{p}(/)?({s})");
60 Self(Regex::new(&s).ok())
61 }
62
63 #[must_use]
64 pub fn ignores(&self, p: &Path) -> bool {
65 let Some(p) = p.to_str() else { return false };
66 if cfg!(target_os = "windows") {
67 let p = p[3..].replace(PathBuf::PATH_SEPARATOR,"/");
68 self.0.as_ref().is_some_and(|r| r.is_match(&p))
69 } else {
70 self.0.as_ref().is_some_and(|r| r.is_match(p))
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 fn get_ignore(source: &Path) -> IgnoreSource {
79 IgnoreSource::new("*/code/*|*/tikz/*|*/tutorial/solution/*", source)
80 }
81
82 #[test]
83 fn ignore_test() {
84 let source = Path::new(if cfg!(target_os = "windows") {"C:\\home\\user\\MathHub\\sTeX\\Documentation\\source"} else {"/home/user/MathHub/sTeX/Documentation/source"});
85 let ignore = get_ignore(source);
86 let path = Path::new(
87 if cfg!(target_os = "windows") {
88 "c:\\home\\user\\MathHub\\sTeX\\Documentation\\source\\tutorial/solution\\preamble.tex"
89 } else {"/home/user/MathHub/sTeX/Documentation/source/tutorial/solution/preamble.tex"},
90 );
91 assert!(ignore.ignores(path),"{ignore} matches {}",path.display());
92 let path = Path::new(
93 if cfg!(target_os = "windows") {
94 "C:\\home\\user\\MathHub\\sTeX\\Documentation\\source\\tutorial\\math\\assertions.en.tex"
95 } else {"/home/user/MathHub/sTeX/Documentation/source/tutorial/math/assertions.en.tex"},
96 );
97 assert!(!ignore.ignores(path),"{ignore} matches {}",path.display());
98 }
99}