archetect_core/
rules.rs

1use std::path::Path;
2
3use linked_hash_map::LinkedHashMap;
4use log::trace;
5
6use crate::config::{Pattern, RuleAction, RuleConfig};
7
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct RulesContext {
10    overwrite: bool,
11    #[serde(skip_serializing_if = "Option::is_none")]
12    path_rules: Option<LinkedHashMap<String, RuleConfig>>,
13    break_triggered: bool,
14}
15
16impl RulesContext {
17    pub fn new() -> RulesContext {
18        RulesContext {
19            overwrite: false,
20            path_rules: None,
21            break_triggered: false,
22        }
23    }
24
25    pub fn set_overwrite(&mut self, overwrite: bool) {
26        self.overwrite = overwrite;
27    }
28
29    pub fn overwrite(&self) -> bool {
30        self.overwrite
31    }
32
33    pub fn path_rules_mut(&mut self) -> Option<&mut LinkedHashMap<String, RuleConfig>> {
34        self.path_rules.as_mut()
35    }
36
37    pub fn path_rules(&self) -> Option<&LinkedHashMap<String, RuleConfig>> {
38        self.path_rules.as_ref()
39    }
40
41    pub fn break_triggered(&self) -> bool {
42        self.break_triggered
43    }
44
45    pub fn set_break_triggered(&mut self, break_triggered: bool) {
46        self.break_triggered = break_triggered;
47    }
48
49    pub fn insert_path_rules(&mut self, insert: &LinkedHashMap<String, RuleConfig>) {
50        let mut results = insert.clone();
51        let path_rules = self.path_rules.get_or_insert_with(|| LinkedHashMap::new());
52        for (name, options) in path_rules {
53            results.insert(name.to_owned(), options.clone());
54        }
55        self.path_rules = Some(results);
56    }
57
58    pub fn append_path_rules(&mut self, append: &LinkedHashMap<String, RuleConfig>) {
59        let path_rules = self.path_rules.get_or_insert_with(|| LinkedHashMap::new());
60        for (name, options) in append {
61            path_rules.insert(name.to_owned(), options.clone());
62        }
63    }
64
65    pub fn get_source_action<P: AsRef<Path>>(&self, path: P) -> RuleAction {
66        if let Some(path_rules) = self.path_rules() {
67            let path = path.as_ref();
68            for (name, path_rule) in path_rules {
69                for pattern in path_rule.patterns() {
70                    match pattern {
71                        Pattern::GLOB(pattern) => {
72                            let matcher = glob::Pattern::new(pattern).unwrap();
73                            if matcher.matches_path(&path) {
74                                trace!(
75                                    "Source Rule [{}: {:?} {:?}] matched '{}'",
76                                    name,
77                                    &path_rule.action(),
78                                    pattern,
79                                    path.display()
80                                );
81                                return path_rule.action().clone();
82                            }
83                        }
84                        _ => unimplemented!(),
85                    }
86                }
87            }
88        }
89        RuleAction::RENDER
90    }
91}
92
93#[derive(Debug, Serialize, Deserialize, Clone)]
94pub enum WriteRule {
95    #[serde(rename = "IF_MISSING")]
96    IsMissing,
97    #[serde(rename = "ALWAYS")]
98    Always,
99}