lsp_max/closure_channel/
decoder.rs1use super::diagnostics::LSPMAX_PROSE_CLOSURE_TOKEN_REFUSED;
2use super::grammar::PROSE_CLOSURE_TOKENS;
3use super::packet::ClosurePacket;
4
5pub struct DecoderResult {
6 pub q: u8,
7 pub diagnostics: Vec<String>,
8}
9
10pub fn decode(text: &str, packet: &ClosurePacket) -> DecoderResult {
11 let mut diagnostics = Vec::new();
12
13 let mut in_string = false;
15 let mut escaped = false;
16 let mut outside_text = String::new();
17
18 for c in text.chars() {
19 if escaped {
20 escaped = false;
21 if !in_string {
22 outside_text.push(c);
23 }
24 continue;
25 }
26 if c == '\\' {
27 escaped = true;
28 if !in_string {
29 outside_text.push(c);
30 }
31 continue;
32 }
33 if c == '"' {
34 in_string = !in_string;
35 outside_text.push(' ');
36 continue;
37 }
38 if !in_string {
39 outside_text.push(c);
40 }
41 }
42
43 let lower_outside = outside_text.to_lowercase();
44 let mut refused = false;
45 for token in PROSE_CLOSURE_TOKENS {
46 if lower_outside.contains(&token.to_lowercase()) {
47 refused = true;
48 break;
49 }
50 }
51
52 if refused {
53 diagnostics.push(LSPMAX_PROSE_CLOSURE_TOKEN_REFUSED.to_string());
54 return DecoderResult { q: 0, diagnostics };
55 }
56
57 let valid_q = packet.f_t == 0 && packet.w_t == 1 && packet.c_t == 1 && !packet.r_b.is_empty();
58
59 DecoderResult {
60 q: if valid_q { 1 } else { 0 },
61 diagnostics,
62 }
63}