tramex_tools/interface/parser/
parser_rrc.rs1use super::ParsingError;
3use crate::data::{AdditionalInfos, Trace};
4use std::str::FromStr;
5
6use crate::interface::{functions::extract_hexe, layer::Layer, types::Direction};
7
8use super::FileParser;
9
10#[derive(Debug, Clone)]
11pub struct RRCInfos {
13 pub direction: Direction,
15
16 pub canal: String,
18
19 pub canal_msg: String,
21}
22
23pub struct RRCParser;
25
26impl RRCParser {
27 fn parse_lines(lines: &[String]) -> Result<(Vec<u8>, Vec<String>), ParsingError> {
29 let lines_len = lines.len();
30 let mut ix = 0;
31 let mut hex_str: Vec<&str> = vec![];
32 while ix < lines_len {
33 match lines[ix].trim_start().chars().next() {
34 Some(c) => {
35 if c == '{' {
36 break;
37 }
38 }
39 None => {
40 break;
41 }
42 }
43 hex_str.push(&lines[ix]);
44 ix += 1;
45 }
46 if ix >= lines_len {
47 return Err(ParsingError::new(
48 "Could not find the end of the hexadecimal".to_string(),
49 ix as u64,
50 ));
51 }
52 let hex = match extract_hexe(&hex_str) {
53 Ok(h) => h,
54 Err(e) => return Err(ParsingError::new(e.message, ix as u64)),
55 };
56
57 let mut end = false;
58 let mut brackets: i16 = 0;
59 let start_block = ix;
60 while (ix < lines_len) && !end {
61 brackets += count_brackets(&lines[ix]);
62 ix += 1;
63 if brackets == 0 {
64 end = true;
65 }
66 }
67 if ix >= lines_len && !end {
68 return Err(ParsingError::new(
69 "Could not parse the JSON like part, missing closing }".to_string(),
70 ix as u64,
71 ));
72 }
73 let text = lines[start_block..ix].iter().map(|s| s.to_string()).collect();
74 Ok((hex, text))
75 }
76}
77
78impl FileParser for RRCParser {
79 fn parse_additional_infos(lines: &[String]) -> Result<AdditionalInfos, ParsingError> {
80 let line = &lines[0];
81 let parts: Vec<&str> = line.split_whitespace().collect();
82 if parts.len() < 5 {
83 return Err(ParsingError::new("Could not find enough (5) parameters".to_string(), 1));
84 }
85 let direction_result = Direction::from_str(parts[2]);
86 let binding: String = parts[5..].join(" ");
87 let concatenated: Vec<&str> = binding.split(':').collect();
88 let direction = match direction_result {
89 Ok(d) => d,
90 Err(_) => {
91 return Err(ParsingError::new(
92 format!("The direction could not be parsed in the part {:?} of {}", parts[2], line),
93 1,
94 ))
95 }
96 };
97 if concatenated.len() < 2 || concatenated[0].is_empty() || concatenated[1].is_empty() {
98 return Err(ParsingError::new(
99 "The canal and/or canal message could not be parsed".to_string(),
100 1,
101 ));
102 }
103 return Ok(AdditionalInfos::RRCInfos(RRCInfos {
104 direction,
105 canal: concatenated[0].to_owned(),
106 canal_msg: concatenated[1].trim_start().to_owned(),
107 }));
108 }
109
110 fn parse(lines: &[String]) -> Result<Trace, ParsingError> {
111 let mtype = match Self::parse_additional_infos(lines) {
112 Ok(m) => m,
113 Err(e) => {
114 return Err(e);
115 }
116 };
117 let (hexa, text) = match Self::parse_lines(&lines[1..]) {
118 Ok((h, t)) => (h, t),
119 Err(e) => {
120 return Err(e);
121 }
122 };
123 let trace = Trace {
124 timestamp: 0,
125 layer: Layer::RRC,
126 additional_infos: mtype,
127 hexa,
128 text: Some(text),
129 };
130 Ok(trace)
131 }
132}
133
134#[inline]
136pub fn count_brackets(hay: &str) -> i16 {
137 let mut count: i16 = 0;
138 for ch in hay.chars() {
139 match ch {
140 '{' => count += 1,
141 '}' => count -= 1,
142 _ => (),
143 }
144 }
145 count
146}