neutralts/
block_parser.rs1use serde_json::json;
2use crate::{
3 constants::*,
4 utils::*,
5 shared::Shared,
6 bif::Bif
7};
8
9pub(crate) struct BlockInherit {
10 pub(crate) indir: String,
11 pub(crate) last_bif_out: bool,
12 pub(crate) last_coalesce_out: bool,
13 pub(crate) block_count: u64, pub(crate) bif_count: u64, pub(crate) alias: String,
16 pub(crate) current_file: String,
17 pub(crate) current_dir: String,
18 pub(crate) include_files: Vec<String>,
19 pub(crate) locale_files: Vec<String>,
20 pub(crate) data_files: Vec<String>,
21 pub(crate) in_cache: bool,
22 pub(crate) in_only: bool,
23}
24
25impl Clone for BlockInherit {
26 fn clone(&self) -> Self {
27 BlockInherit {
28 indir: self.indir.clone(),
29 last_bif_out: self.last_bif_out,
30 last_coalesce_out: self.last_coalesce_out,
31 block_count: self.block_count,
32 bif_count: self.bif_count,
33 alias: self.alias.clone(),
34 current_file: self.current_file.clone(),
35 current_dir: self.current_dir.clone(),
36 include_files: self.include_files.clone(),
37 locale_files: self.locale_files.clone(),
38 data_files: self.data_files.clone(),
39 in_cache: self.in_cache,
40 in_only: self.in_only,
41 }
42 }
43}
44
45impl BlockInherit {
46 pub(crate) fn new() -> Self {
47 BlockInherit {
48 indir: "block_0".to_string(),
49 last_bif_out: false,
50 last_coalesce_out: false,
51 block_count: 0,
52 bif_count: 0,
53 alias: String::new(),
54 current_file: String::new(),
55 current_dir: String::new(),
56 include_files: Vec::new(),
57 locale_files: Vec::new(),
58 data_files: Vec::new(),
59 in_cache: false,
60 in_only: false,
61 }
62 }
63
64 pub(crate) fn create_block_schema(&mut self, shared: &mut Shared) -> String {
70 let prev_id = self.indir.clone();
71 let block_id;
72
73 if self.block_count < 1 {
77 block_id = "block_1".to_string();
78 } else {
79 block_id = "block_".to_string() + self.block_count.to_string().as_str();
80 }
81
82 if prev_id != block_id {
85 shared.schema["__indir"][&block_id] = shared.schema["__indir"][&prev_id].clone();
86 }
87
88 self.indir = block_id.clone();
89
90 block_id
91 }
92}
93
94
95pub(crate) struct BlockParser<'a> {
96 shared: &'a mut Shared,
97 inherit: BlockInherit,
98 _none: &'a str,
99}
100
101impl Drop for BlockParser<'_> {
102 fn drop(&mut self) {
103 let block_id = "block_".to_string() + self.inherit.block_count.to_string().as_str();
105
106 if block_id != "block_1" {
108 if block_id == self.inherit.indir && is_defined_key(&self.shared.schema["__indir"], &block_id) {
109 self.shared.schema["__indir"][&block_id] = json!({});
110 }
111 }
112 }
113}
114
115impl<'a> BlockParser<'a> {
116 pub(crate) fn new(shared: &'a mut Shared, inherit: &BlockInherit) -> Self {
117 let mut inherit = inherit.clone();
118 inherit.block_count += 1;
119
120 BlockParser {
121 shared,
122 inherit,
123 _none: "",
124 }
125 }
126
127 pub(crate) fn update_indir(&mut self, indir: &String) {
128 self.shared.schema["__indir"][indir] =
129 self.shared.schema["__indir"][&self.inherit.indir].clone();
130 }
131
132 pub(crate) fn parse(&mut self, raw_source: &'a str, only: &str) -> String {
133 let blocks;
134
135 match extract_blocks(raw_source) {
136 Ok(b) => {
137 blocks = b;
138 }
139 Err(p) => {
140 self.shared.status_code = "500".to_string();
141 self.shared.status_param = format!("Unmatched block at position {}", p);
142 eprintln!("Unmatched block at position {}", p);
143
144 if let Some(text) = STATUS_CODES.get(self.shared.status_code.as_str()) {
145 self.shared.status_text = text.to_string();
146 } else {
147 self.shared.status_text = EMPTY_STRING;
148 }
149
150 return EMPTY_STRING;
151 }
152 }
153
154 let mut prev_end = 0;
155 let mut out = String::new();
156 for (start, end) in blocks {
157 let is_comment = raw_source[start..end].starts_with(BIF_COMMENT_OPEN);
158 let is_short_circuit_coalesce =
159 self.inherit.last_coalesce_out && self.inherit.alias == "coalesce";
160
161 if self.shared.exit {
162 return out.clone();
163 }
164
165 if prev_end < start {
166 out += &raw_source[prev_end..start];
167 }
168
169 if !is_comment && !is_short_circuit_coalesce {
170 let mut bif =
171 Bif::new(&raw_source[start..end], self.shared, &mut self.inherit, only);
172 out += &bif.parse();
173 }
174
175 prev_end = end;
176 }
177 out += &raw_source[prev_end..];
178
179 out.trim().to_string()
180 }
181}