1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use serde::de::Visitor;
use serde::{Deserialize, Serialize};
use crate::commands::execution::{ConditionExecution, ConditionResult};
use crate::context::PicoContext;
use crate::rules::PicoRules;
use crate::runtime::PicoRuntime;
use regex::Regex;
#[derive(Serialize, Debug)]
#[serde(untagged)]
pub enum VarExistence {
SingleVar(String),
ManyVar(Vec<String>),
}
#[derive(Debug)]
struct VarExistsVisitor;
impl<'de> Visitor<'de> for VarExistsVisitor {
type Value = VarExistence;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
error!("varexistvistior: expecting {:?}", self);
formatter.write_str("string or array of strings")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
info!("Checking value: {}", value);
let re: Regex = Regex::new("^[a-z]+$").unwrap();
if re.is_match(value) {
return Ok(VarExistence::SingleVar(value.to_string()));
}
Ok(VarExistence::SingleVar(value.to_string()))
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: serde::de::StdError,
{
Ok(VarExistence::SingleVar(value.to_string()))
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut arr = Vec::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(item) = seq.next_element()? {
arr.push(item);
}
info!("VarExistVisitor - seq {:?}", arr);
Ok(VarExistence::ManyVar(arr))
}
}
impl<'de> Deserialize<'de> for VarExistence {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(VarExistsVisitor)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct VarExistsCondition {
exists: VarExistence,
}
impl ConditionExecution for VarExistsCondition {
fn run_with_context(
&self,
pico_rules: &PicoRules,
_runtime: &mut PicoRuntime,
ctx: &mut PicoContext,
) -> ConditionResult {
match &self.exists {
VarExistence::SingleVar(s) => {
if let Some(_v) = ctx.get_value(s) {
return Ok(true);
}
}
VarExistence::ManyVar(vs) => {
for v in vs {
match ctx.get_value(v) {
None => return Ok(false),
Some(_) => {}
}
}
return Ok(true);
}
}
Ok(false)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct VarMissingCondition {
missing: String,
}
impl ConditionExecution for VarMissingCondition {
fn run_with_context(
&self,
_pico_rules: &PicoRules,
_runtime: &mut PicoRuntime,
ctx: &mut PicoContext,
) -> ConditionResult {
match ctx.get_value(&self.missing) {
Some(_v) => Ok(false),
None => Ok(true),
}
}
}