tramex_tools/interface/interface_file/
file_handler.rs

1//! File Handler
2
3use crate::data::Data;
4use crate::data::Trace;
5use crate::errors::ErrorCode;
6use crate::errors::TramexError;
7use crate::interface::interface_types::InterfaceTrait;
8use crate::interface::layer::Layers;
9use crate::tramex_error;
10use std::path::PathBuf;
11
12use super::utils_file::parse_one_block;
13
14/// The default number of log processed by batch
15const DEFAULT_NB: usize = 50;
16#[derive(Debug, Clone)]
17/// Data structure to store the file.
18pub struct File {
19    /// Path of the file.
20    pub file_path: PathBuf,
21
22    /// Content of the file.
23    pub file_content: Vec<String>,
24
25    /// Full read status of the file.
26    pub full_read: bool,
27
28    /// the number of log to read each batch
29    nb_read: usize,
30
31    /// The previous line number
32    index_line: usize,
33
34    /// Available
35    pub available: bool,
36}
37
38impl Default for File {
39    fn default() -> Self {
40        Self {
41            file_path: PathBuf::from(""),
42            file_content: vec![],
43            full_read: false,
44            nb_read: DEFAULT_NB,
45            index_line: 0,
46            available: true,
47        }
48    }
49}
50
51impl InterfaceTrait for File {
52    fn get_more_data(&mut self, _layer_list: Layers, data: &mut Data) -> Result<(), Vec<TramexError>> {
53        if self.full_read {
54            return Ok(());
55        }
56        let (mut traces, err_processed) = self.process();
57        data.events.append(&mut traces);
58        if !err_processed.is_empty() {
59            let filtered = err_processed
60                .iter()
61                .filter(|x| !matches!(x.get_code(), ErrorCode::EndOfFile))
62                .cloned()
63                .collect();
64            return Err(filtered);
65        }
66        Ok(())
67    }
68
69    fn close(&mut self) -> Result<(), TramexError> {
70        Ok(())
71    }
72}
73
74impl File {
75    /// Create a new file.
76    pub fn new(file_path: PathBuf, file_content: String) -> Self {
77        Self {
78            file_path,
79            file_content: file_content.lines().map(|x| x.to_string()).collect(),
80            full_read: false,
81            nb_read: DEFAULT_NB,
82            index_line: 0,
83            available: true,
84        }
85    }
86
87    /// set file mode using a path and content
88    pub fn new_file_content(file_path: PathBuf, file_content: String) -> Self {
89        Self {
90            file_path,
91            file_content: file_content.lines().map(|x| x.to_string()).collect(),
92            full_read: false,
93            nb_read: DEFAULT_NB,
94            index_line: 0,
95            available: true,
96        }
97    }
98
99    /// To update the number of log to read per batch
100    pub fn change_nb_read(&mut self, toread: usize) {
101        self.nb_read = toread;
102    }
103
104    /// To process the file and parse a batch of log
105    pub fn process(&mut self) -> (Vec<Trace>, Vec<TramexError>) {
106        let (vec_trace, opt_err) = File::process_string(&self.file_content, self.nb_read, &mut self.index_line);
107        for one_error in &opt_err {
108            if matches!(one_error.get_code(), ErrorCode::EndOfFile) {
109                self.full_read = true;
110            }
111        }
112        (vec_trace, opt_err)
113    }
114    /// To process a string passed in argument, with index and batch to read
115    pub fn process_string(lines: &[String], nb_to_read: usize, ix: &mut usize) -> (Vec<Trace>, Vec<TramexError>) {
116        let mut traces = vec![];
117        let mut errors = vec![];
118        for _ in 0..nb_to_read {
119            if *ix >= lines.len() {
120                errors.push(tramex_error!("End of file".to_string(), ErrorCode::EndOfFile));
121                break;
122            }
123            match parse_one_block(&lines[*ix..], ix) {
124                Ok(trace) => {
125                    traces.push(trace);
126                }
127                Err(err) => {
128                    log::error!("{}", err.message);
129                    errors.push(err);
130                }
131            };
132        }
133        (traces, errors)
134    }
135}