tramex_tools/interface/parser/
parser_rrc.rs

1//! Parser for RRC traces
2use super::ParsingError;
3use super::hex_extractor::extract_binary_from_lines;
4use crate::data::{AdditionalInfos, Trace};
5use crate::interface::association::TraceRelation;
6use std::str::FromStr;
7
8use crate::interface::{layer::Layer, types::Direction};
9
10use super::FileParser;
11
12#[derive(Debug, Clone)]
13/// Data structure to store the message type (from the amarisoft API)
14pub struct RRCInfos {
15    /// Direction of the message.
16    pub direction: Direction,
17
18    /// canal of the message.
19    pub canal: String,
20
21    /// Message of the canal.
22    pub canal_msg: String,
23}
24
25/// RRC Parser
26pub struct RRCParser;
27
28impl RRCParser {
29    /// Parse the lines
30    fn parse_lines(lines: &[String]) -> Vec<String> {
31        lines.to_vec()
32    }
33}
34
35impl FileParser for RRCParser {
36    fn parse_additional_infos(lines: &[String]) -> Result<AdditionalInfos, ParsingError> {
37        let line = &lines[0];
38        let parts: Vec<&str> = line.split_whitespace().collect();
39        if parts.len() < 5 {
40            return Err(ParsingError::new("Could not find enough (5) parameters".to_string(), 1));
41        }
42        let direction_result = Direction::from_str(parts[2]);
43        let binding: String = parts[5..].join(" ");
44        let concatenated: Vec<&str> = binding.split(':').collect();
45        let direction = match direction_result {
46            Ok(d) => d,
47            Err(_) => {
48                return Err(ParsingError::new(
49                    format!("The direction could not be parsed in the part {:?} of {}", parts[2], line),
50                    1,
51                ));
52            }
53        };
54        if concatenated.len() < 2 || concatenated[0].is_empty() || concatenated[1].is_empty() {
55            return Err(ParsingError::new(
56                "The canal and/or canal message could not be parsed".to_string(),
57                1,
58            ));
59        }
60        Ok(AdditionalInfos::RRCInfos(RRCInfos {
61            direction,
62            canal: concatenated[0].to_owned(),
63            canal_msg: concatenated[1].trim_start().to_owned(),
64        }))
65    }
66
67    fn parse(lines: &[String]) -> Result<Trace, ParsingError> {
68        let mtype = match Self::parse_additional_infos(lines) {
69            Ok(m) => m,
70            Err(e) => {
71                return Err(e);
72            }
73        };
74        let text = Self::parse_lines(lines);
75        let binary = extract_binary_from_lines(lines);
76
77        // Parse timestamp from first line
78        let timestamp = if let Some(first_line) = lines.first() {
79            super::parse_timestamp(first_line)?
80        } else {
81            0
82        };
83
84        let trace = Trace {
85            timestamp,
86            layer: Layer::RRC,
87            additional_infos: mtype,
88            text: Some(text),
89            binary,
90            relation: TraceRelation::default(),
91        };
92        Ok(trace)
93    }
94}
95
96/// Counting Brackets
97#[inline]
98pub fn count_brackets(hay: &str) -> i16 {
99    let mut count: i16 = 0;
100    for ch in hay.chars() {
101        match ch {
102            '{' => count += 1,
103            '}' => count -= 1,
104            _ => (),
105        }
106    }
107    count
108}