log_analyzer/models/
log_line_styled.rs

1use std::cmp::Ordering;
2
3use serde::{Deserialize, Serialize};
4
5use super::log_line::LogLine;
6
7#[derive(Default, Serialize, Deserialize, Clone, Debug)]
8#[serde(default)]
9/// This struct contains a formated log with its info clasified
10/// in several fields
11pub struct LogLineStyled {
12    pub log: Vec<(Option<String>, String)>,
13    pub index: Vec<(Option<String>, String)>,
14    pub date: Vec<(Option<String>, String)>,
15    pub timestamp: Vec<(Option<String>, String)>,
16    pub app: Vec<(Option<String>, String)>,
17    pub severity: Vec<(Option<String>, String)>,
18    pub function: Vec<(Option<String>, String)>,
19    pub payload: Vec<(Option<String>, String)>,
20    pub color: Option<(u8, u8, u8)>,
21}
22
23impl LogLineStyled {
24    /// Returns the available fields
25    pub fn columns() -> Vec<String> {
26        vec![
27            "Log".to_string(),
28            "Index".to_string(),
29            "Date".to_string(),
30            "Timestamp".to_string(),
31            "App".to_string(),
32            "Severity".to_string(),
33            "Function".to_string(),
34            "Payload".to_string(),
35        ]
36    }
37
38    /// Gets the field value with the `columns` returned key
39    pub fn get(&self, key: &str) -> Option<&Vec<(Option<String>, String)>> {
40        match key {
41            "Log" => Some(&self.log),
42            "Index" => Some(&self.index),
43            "Date" => Some(&self.date),
44            "Timestamp" => Some(&self.timestamp),
45            "App" => Some(&self.app),
46            "Severity" => Some(&self.severity),
47            "Function" => Some(&self.function),
48            "Payload" => Some(&self.payload),
49            _ => None,
50        }
51    }
52
53    /// Gets a (key, value) like representation of some fields
54    pub fn values(&self) -> Vec<(&str, &Vec<(Option<String>, String)>)> {
55        vec![
56            ("Log", &self.log),
57            ("Date", &self.date),
58            ("Timestamp", &self.timestamp),
59            ("App", &self.app),
60            ("Severity", &self.severity),
61            ("Function", &self.function),
62            ("Payload", &self.payload),
63        ]
64    }
65
66
67    /// Return a copy of this line with unformatted content
68    pub fn unformat(&self) -> LogLine {
69        let unformat = |groups: &Vec<(Option<String>, String)>| {
70            groups.into_iter().fold(String::new(), |acc, g| acc + &g.1)
71        };
72
73        LogLine {
74            log: unformat(&self.log),
75            index: unformat(&self.index),
76            date: unformat(&self.date),
77            timestamp: unformat(&self.timestamp),
78            app: unformat(&self.app),
79            severity: unformat(&self.severity),
80            function: unformat(&self.function),
81            payload: unformat(&self.payload),
82            color: self.color,
83        }
84    }
85}
86
87impl IntoIterator for LogLineStyled {
88    type Item = Vec<(Option<String>, String)>;
89    type IntoIter = std::array::IntoIter<Vec<(Option<String>, String)>, 7>;
90
91    fn into_iter(self) -> Self::IntoIter {
92        IntoIterator::into_iter([
93            self.log,
94            self.date,
95            self.timestamp,
96            self.app,
97            self.severity,
98            self.function,
99            self.payload,
100        ])
101    }
102}
103
104impl<'a> IntoIterator for &'a LogLineStyled {
105    type Item = &'a Vec<(Option<String>, String)>;
106    type IntoIter = std::array::IntoIter<&'a Vec<(Option<String>, String)>, 7>;
107
108    fn into_iter(self) -> Self::IntoIter {
109        IntoIterator::into_iter([
110            &self.log,
111            &self.date,
112            &self.timestamp,
113            &self.app,
114            &self.severity,
115            &self.function,
116            &self.payload,
117        ])
118    }
119}
120
121impl<'a> IntoIterator for &'a mut LogLineStyled {
122    type Item = &'a Vec<(Option<String>, String)>;
123    type IntoIter = std::array::IntoIter<&'a Vec<(Option<String>, String)>, 7>;
124
125    fn into_iter(self) -> Self::IntoIter {
126        IntoIterator::into_iter([
127            &self.log,
128            &self.date,
129            &self.timestamp,
130            &self.app,
131            &self.severity,
132            &self.function,
133            &self.payload,
134        ])
135    }
136}
137
138impl<'a> IntoIterator for &'a &'a mut LogLineStyled {
139    type Item = &'a Vec<(Option<String>, String)>;
140    type IntoIter = std::array::IntoIter<&'a Vec<(Option<String>, String)>, 7>;
141
142    fn into_iter(self) -> Self::IntoIter {
143        IntoIterator::into_iter([
144            &self.log,
145            &self.date,
146            &self.timestamp,
147            &self.app,
148            &self.severity,
149            &self.function,
150            &self.payload,
151        ])
152    }
153}
154impl<'a> IntoIterator for &'a &'a LogLineStyled {
155    type Item = &'a Vec<(Option<String>, String)>;
156    type IntoIter = std::array::IntoIter<&'a Vec<(Option<String>, String)>, 7>;
157
158    fn into_iter(self) -> Self::IntoIter {
159        IntoIterator::into_iter([
160            &self.log,
161            &self.date,
162            &self.timestamp,
163            &self.app,
164            &self.severity,
165            &self.function,
166            &self.payload,
167        ])
168    }
169}
170
171impl Ord for LogLineStyled {
172    fn cmp(&self, other: &Self) -> Ordering {
173        match (self.unformat().index.parse::<usize>(), other.unformat().index.parse::<usize>()) {
174            (Ok(index), Ok(other)) => match (index, other) {
175                (index, other) if index < other => Ordering::Less,
176                (index, other) if index == other => Ordering::Equal,
177                _ => Ordering::Greater,
178            },
179            _ => Ordering::Equal,
180        }
181    }
182}
183
184impl PartialOrd for LogLineStyled {
185    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
186        match (self.unformat().index.parse::<usize>(), other.unformat().index.parse::<usize>()) {
187            (Ok(index), Ok(other)) => match (index, other) {
188                (index, other) if index < other => Some(Ordering::Less),
189                (index, other) if index == other => Some(Ordering::Equal),
190                _ => Some(Ordering::Greater),
191            },
192            _ => None,
193        }
194    }
195}
196
197impl PartialEq for LogLineStyled {
198    fn eq(&self, other: &Self) -> bool {
199        self.index == other.index
200            && self.date == other.date
201            && self.timestamp == other.timestamp
202            && self.app == other.app
203            && self.severity == other.severity
204            && self.function == other.function
205            && self.payload == other.payload
206            && self.color == other.color
207    }
208}
209
210impl Eq for LogLineStyled {}