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
use crate::data::ast::Interval;
use crate::data::csml_bot::CsmlBot;
use crate::data::position::Position;
use crate::error_format::gen_error_info;
use crate::error_format::ErrorInfo;
use crate::linter::data::Linter;
use lazy_static::*;
type CsmlRules = fn(bot: &CsmlBot, linter: &Linter, error: &mut Vec<ErrorInfo>);
lazy_static! {
static ref FUNCTIONS: Vec<CsmlRules> = {
let mut vector: Vec<CsmlRules> = Vec::new();
vector.push(check_missing_flow);
vector.push(check_valid_flow);
vector.push(check_duplicate_step);
vector.push(check_valid_goto);
vector
};
}
fn check_missing_flow(_bot: &CsmlBot, linter: &Linter, error: &mut Vec<ErrorInfo>) {
if linter.flow.is_empty() {
error.push(gen_error_info(
Position::new(Interval::new_as_u32(0, 0)),
"LINTER: Need to have at least one Flow".to_owned(),
));
}
}
fn check_valid_flow(_bot: &CsmlBot, linter: &Linter, error: &mut Vec<ErrorInfo>) {
for flow in linter.flow.keys() {
Position::set_flow(&flow);
let mut result = false;
if let Some(hashmap) = linter.flow.get(flow) {
for step in hashmap.keys() {
if step == "start" {
result = true;
}
}
Position::set_step("");
if !result {
error.push(gen_error_info(
Position::new(Interval::new_as_u32(0, 0)),
format!("LINTER: Flow '{}' need to have a 'start' step", flow),
));
}
}
}
}
fn check_duplicate_step(_bot: &CsmlBot, linter: &Linter, error: &mut Vec<ErrorInfo>) {
for flow in linter.flow.keys() {
Position::set_flow(&flow);
if let Some(hashmap_step) = linter.flow.get(flow) {
for step in hashmap_step.keys() {
Position::set_step(&step);
if let Some(vector_step) = hashmap_step.get(step) {
if vector_step.len() > 1 {
error.push(gen_error_info(
Position::new(*vector_step.last().unwrap()),
format!("LINTER: Duplicate step '{}' in flow '{}'", step, flow),
));
}
}
}
}
}
}
fn check_valid_goto(_bot: &CsmlBot, linter: &Linter, error: &mut Vec<ErrorInfo>) {
for goto in linter.goto.iter() {
Position::set_flow(&goto.src_flow);
Position::set_step(&goto.src_step);
match linter.flow.get(&goto.dst_flow) {
Some(step) => {
if !step.contains_key(&goto.dst_step) && goto.dst_step != "end" {
error.push(gen_error_info(
Position::new(goto.interval),
format!("LINTER: Step '{}' doesn't exist", goto.dst_step),
));
}
}
None => {
error.push(gen_error_info(
Position::new(goto.interval),
format!("LINTER: Flow '{}' doesn't exist", goto.dst_flow),
));
}
}
}
}
pub fn lint_flow(bot: &CsmlBot, mut error: &mut Vec<ErrorInfo>) {
let linter = Linter::get_linter();
for f in FUNCTIONS.iter() {
f(bot, &linter, &mut error);
}
}