ninja_files_data2/rule/
builder.rs1use std::collections::BTreeMap;
2
3use crate::{
4 Command, CommandBuilder, CommandBuilderError, InvalidVariable, InvalidVariableId, Rule,
5 Variable, VariableId,
6};
7
8pub struct RuleBuilder {
9 command: Option<Command>,
10 shadow: BTreeMap<VariableId, Variable>,
11 generator: bool,
12 errors: Vec<RuleBuilderError>,
13}
14
15#[derive(Clone, Debug)]
16pub enum RuleBuilderError {
17 InvalidCommand(Vec<CommandBuilderError>),
18 InvalidVariableId(InvalidVariableId),
19 InvalidVariable(InvalidVariable),
20 VariableAlreadyDefined {
21 id: VariableId,
22 previous: Variable,
23 var: Variable,
24 },
25}
26
27impl RuleBuilder {
28 pub fn new<C>(command_builder: C) -> Self
29 where
30 C: Into<CommandBuilder>,
31 {
32 let mut command = None;
33 let mut errors = vec![];
34 match command_builder.into().build() {
35 Ok(com) => command = Some(com),
36 Err(err) => errors.push(RuleBuilderError::InvalidCommand(err)),
37 };
38 RuleBuilder {
39 command,
40 shadow: BTreeMap::new(),
41 generator: false,
42 errors,
43 }
44 }
45
46 pub fn build(&self) -> Result<Rule, Vec<RuleBuilderError>> {
47 let errors = self.errors.clone();
48 let shadow = self.shadow.clone();
49 let generator = self.generator;
50
51 if !self.errors.is_empty() {
52 return Err(errors);
53 }
54
55 let command = self.command.clone().unwrap();
57
58 let rule = Rule {
59 command,
60 shadow,
61 generator,
62 };
63 Ok(rule)
64 }
65
66 pub fn generator(mut self, generator: bool) -> Self {
67 self.generator = generator;
68 self
69 }
70
71 pub fn variable<Id, Var>(mut self, id: Id, var: Var) -> Self
72 where
73 Id: AsRef<str>,
74 Var: AsRef<str>,
75 {
76 let id = VariableId::try_create(id);
77 let var = Variable::try_create(var);
78 match (id, var) {
79 (Ok(id), Ok(var)) => match self.shadow.insert(id.clone(), var.clone()) {
80 Some(previous) if var == previous => (),
81 Some(previous) => {
82 self.errors
83 .push(RuleBuilderError::VariableAlreadyDefined { id, previous, var })
84 }
85 None => (),
86 },
87 (Ok(_), Err(v)) => self.errors.push(RuleBuilderError::InvalidVariable(v)),
88 (Err(i), Ok(_)) => self.errors.push(RuleBuilderError::InvalidVariableId(i)),
89 (Err(i), Err(v)) => {
90 self.errors.push(RuleBuilderError::InvalidVariable(v));
91 self.errors.push(RuleBuilderError::InvalidVariableId(i));
92 }
93 }
94 self
95 }
96}
97
98impl From<Rule> for RuleBuilder {
99 fn from(value: Rule) -> Self {
100 let mut builder = RuleBuilder::new(value.command).generator(value.generator);
101 for (id, var) in value.shadow.into_iter() {
102 builder = builder.variable(id, var);
103 }
104 builder
105 }
106}