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)]
9pub 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 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 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 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 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 {}