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
pub mod data;
pub mod error_format;
pub mod interpreter;
pub mod linter;
pub mod parser;
use crate::data::context::get_hashmap;
use crate::linter::linter::linter;
use crate::linter::Linter;
use data::{ast::*, ContextJson, Data, Event, MessageData, MSG};
use error_format::*;
use interpreter::interpret_scope;
use parser::parse_flow;
use parser::state_context::StateContext;
use curl::easy::Easy;
use std::{collections::HashMap, sync::mpsc};
pub fn search_for<'a>(flow: &'a Flow, name: &str) -> Option<&'a Expr> {
flow.flow_instructions
.get(&InstructionType::NormalStep(name.to_owned()))
}
pub fn execute_step(
flow: &Flow,
name: &str,
mut data: Data,
instruction_index: Option<usize>,
sender: &Option<mpsc::Sender<MSG>>,
) -> Result<MessageData, ErrorInfo> {
match search_for(flow, name) {
Some(Expr::Scope { scope, .. }) => {
interpret_scope(scope, &mut data, instruction_index, sender)
}
_ => Err(gen_error_info(
Interval { line: 0, column: 0 },
format!("{} {}", name, ERROR_STEP_EXIST),
)),
}
}
pub fn parse_file(file: &str) -> Result<Flow, ErrorInfo> {
Linter::clear();
Linter::set_flow("default_flow");
match parse_flow(file) {
Ok(flow) => {
let mut error = Vec::new();
linter(&mut error);
Linter::print_warnings();
match error.is_empty() {
true => Ok(flow),
false => Err(error.first().unwrap().to_owned()),
}
}
Err(e) => Err(e),
}
}
pub fn interpret(
flow: &str,
step_name: &str,
context: ContextJson,
event: &Event,
sender: Option<mpsc::Sender<MSG>>,
) -> MessageData {
let ast: Flow = match parse_file(flow) {
Ok(flow) => flow,
Err(e) => {
StateContext::clear_state();
StateContext::clear_rip();
return MessageData::error_to_message(
Err(gen_error_info(
Interval { line: 0, column: 0 },
format!("{} {}", ERROR_INVALID_FLOW, e.message),
)),
&sender,
);
}
};
let curl = Easy::new();
let mut context = context.to_literal();
let step_vars = match &context.hold {
Some(hold) => get_hashmap(&hold.step_vars),
None => HashMap::new(),
};
let instruction_index = if let Some(hold) = &context.hold {
Some(hold.index)
} else {
None
};
let data = Data {
ast: &ast,
context: &mut context,
event,
curl,
step_vars,
};
MessageData::error_to_message(
execute_step(&ast, &step_name, data, instruction_index, &sender),
&sender,
)
}