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}