Skip to content

Commit d0f1305

Browse files
committed
Merge branch 'develop'
# Conflicts: # Cargo.toml
2 parents 561d121 + 6f4e481 commit d0f1305

16 files changed

+1090
-788
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/target
2-
Cargo.lock
2+
Cargo.lock
3+
.vscode

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "journal1c"
3-
version = "0.2.1"
3+
version = "0.3.0"
44
edition = "2021"
55

66
[dependencies]

src/app.rs

Lines changed: 95 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
use std::{error::Error, time::Duration};
2-
use std::cell::RefCell;
3-
use std::rc::Rc;
1+
use crate::{
2+
parser::{Compiler, FieldMap, Value},
3+
ui::widgets::{KeyValueView, LineEdit, TableView, WidgetExt},
4+
LogCollection, LogParser,
5+
};
46
use chrono::NaiveDateTime;
57
use crossterm::{
68
event,
7-
event::{Event, KeyCode},
9+
event::{Event, KeyCode, KeyModifiers},
810
};
9-
use crossterm::event::KeyModifiers;
11+
use std::{cell::RefCell, error::Error, rc::Rc, time::Duration};
1012
use tui::{
1113
backend::Backend,
12-
Frame,
13-
layout::{Constraint, Direction, Layout}, Terminal,
14+
layout::{Constraint, Direction, Layout},
15+
style::{Color, Style},
16+
text::{Span, Spans, Text},
17+
widgets::Paragraph,
18+
Frame, Terminal,
1419
};
15-
use tui::style::{Color, Style};
16-
use tui::text::{Span, Spans, Text};
17-
use tui::widgets::Paragraph;
18-
use crate::{LogCollection, LogParser, ui::widgets::{WidgetExt, TableView, LineEdit}};
19-
use crate::parser::{Compiler, FieldMap, Value};
20-
use crate::ui::widgets::KeyValueView;
2120

2221
#[derive(Default)]
2322
enum ActiveWidget {
@@ -51,11 +50,9 @@ impl App {
5150
Constraint::Percentage(20),
5251
];
5352

54-
let log_data = Rc::new(RefCell::new(
55-
LogCollection::new(
56-
LogParser::parse(dir, date)
57-
)
58-
));
53+
let log_data = Rc::new(RefCell::new(LogCollection::new(LogParser::parse(
54+
dir, date,
55+
))));
5956

6057
let mut table_view = TableView::new(widths);
6158
table_view.set_model(log_data.clone());
@@ -73,61 +70,64 @@ impl App {
7370

7471
let log_data = Rc::downgrade(&app.log_data);
7572
let table = Rc::downgrade(&app.table);
76-
app.search.borrow_mut().on_changed(move |sender| match log_data.upgrade() {
77-
Some(model) => {
78-
match model.borrow_mut().set_filter(sender.text().to_string()) {
79-
Err(e) => {
73+
app.search
74+
.borrow_mut()
75+
.on_changed(move |sender| match log_data.upgrade() {
76+
Some(model) => match model.borrow_mut().set_filter(sender.text().to_string()) {
77+
Err(e) => {
8078
sender.set_border_text(e.to_string());
8179
sender.set_style(Style::default().fg(Color::Red));
82-
},
80+
}
8381
_ => {
8482
sender.set_border_text(String::new());
8583
sender.set_style(Style::default());
8684
if let Some(table) = table.upgrade() {
8785
table.borrow_mut().reset_state();
8886
}
89-
},
90-
}
91-
},
92-
None => {}
93-
});
87+
}
88+
},
89+
None => {}
90+
});
9491

9592
let text = Rc::downgrade(&app.text);
9693
let log_data = Rc::downgrade(&app.log_data);
97-
app.table.borrow_mut().on_selection_changed(move |_sender, index| {
98-
if let (Some(log_data), Some(text)) = (log_data.upgrade(), text.upgrade()) {
99-
if let Some(index) = index {
100-
if let Some(line) = log_data.borrow().line(index) {
101-
text.borrow_mut().set_data(line.fields);
102-
return
94+
app.table
95+
.borrow_mut()
96+
.on_selection_changed(move |_sender, index| {
97+
if let (Some(log_data), Some(text)) = (log_data.upgrade(), text.upgrade()) {
98+
if let Some(index) = index {
99+
if let Some(line) = log_data.borrow().line(index) {
100+
text.borrow_mut().set_data(line.fields().into());
101+
return;
102+
}
103103
}
104-
}
105104

106-
// Panic if we can't borrow. Because dont need reset state when filter from info widget.
107-
if let Ok(mut borrowed) = text.try_borrow_mut() {
108-
borrowed.set_data(FieldMap::new());
105+
// Panic if we can't borrow. Because dont need reset state when filter from info widget.
106+
if let Ok(mut borrowed) = text.try_borrow_mut() {
107+
borrowed.set_data(FieldMap::new());
108+
}
109109
}
110-
}
111-
});
110+
});
112111

113112
let search = Rc::downgrade(&app.search);
114113
app.text.borrow_mut().on_add_to_filter(move |(key, value)| {
115114
if let Some(search) = search.upgrade() {
116115
let value = match value {
117116
Value::String(s) => format!("\"{}\"", s),
118117
Value::Number(n) => n.to_string(),
118+
Value::DateTime(n) => format!("'{}'", n.format("%Y-%m-%d %H:%M:%S%.9f")),
119119
_ => unreachable!(),
120120
};
121121

122-
123122
let mut search_borrowed = search.borrow_mut();
124123
search_borrowed.show();
125124
let text = search_borrowed.text().to_string();
126125
if text.trim().is_empty() {
127126
search_borrowed.set_text(format!(r#"WHERE {} = {}"#, key, value));
128-
}
129-
else if Compiler::new().compile(text.trim()).is_ok() {
130-
search_borrowed.set_text(format!(r#"{} AND {} = {}"#, text, key, value));
127+
} else if let Ok(query) = Compiler::new().compile(text.trim()) {
128+
if !query.is_regex() {
129+
search_borrowed.set_text(format!(r#"{} AND {} = {}"#, text, key, value));
130+
}
131131
}
132132
}
133133
});
@@ -137,49 +137,52 @@ impl App {
137137

138138
pub fn run<B: Backend>(&mut self, terminal: &mut Terminal<B>) -> Result<(), Box<dyn Error>> {
139139
loop {
140-
141140
terminal.draw(|f| ui(f, self))?;
142141

143142
if event::poll(Duration::from_millis(100))? {
144143
let event = event::read()?;
145144
match event {
146145
Event::Key(key) => match key.code {
147-
KeyCode::Char('q') if key.modifiers == KeyModifiers::CONTROL => return Ok(()),
146+
KeyCode::Char('q') if key.modifiers == KeyModifiers::CONTROL => {
147+
return Ok(())
148+
}
148149
KeyCode::Char('f') if key.modifiers == KeyModifiers::CONTROL => {
149150
match self.state {
150151
ActiveWidget::LogTable | ActiveWidget::InfoView => {
151152
self.search.borrow_mut().set_visible(true);
152153
self.set_active_widget(ActiveWidget::SearchBox);
153-
},
154+
}
154155
ActiveWidget::SearchBox => {
155156
self.search.borrow_mut().set_visible(false);
156157
self.set_active_widget(ActiveWidget::LogTable);
157-
},
158+
}
158159
}
159-
},
160-
KeyCode::Tab => { // Next active widget
160+
}
161+
KeyCode::Tab => {
162+
// Next active widget
161163
match self.state {
162164
ActiveWidget::LogTable => {
163165
self.set_active_widget(ActiveWidget::InfoView);
164-
},
166+
}
165167
ActiveWidget::SearchBox => {
166168
self.set_active_widget(ActiveWidget::LogTable);
167-
},
169+
}
168170
ActiveWidget::InfoView => {
169171
if self.search.borrow().visible() {
170172
self.set_active_widget(ActiveWidget::SearchBox);
171-
}
172-
else {
173+
} else {
173174
self.set_active_widget(ActiveWidget::LogTable);
174175
}
175176
}
176177
}
177178
}
178179
_ => match self.state {
179180
ActiveWidget::LogTable => self.table.borrow_mut().key_press_event(key),
180-
ActiveWidget::SearchBox => self.search.borrow_mut().key_press_event(key),
181+
ActiveWidget::SearchBox => {
182+
self.search.borrow_mut().key_press_event(key)
183+
}
181184
ActiveWidget::InfoView => self.text.borrow_mut().key_press_event(key),
182-
}
185+
},
183186
},
184187
_ => {}
185188
}
@@ -193,12 +196,12 @@ impl App {
193196
self.table.borrow_mut().set_focus(true);
194197
self.search.borrow_mut().set_focus(false);
195198
self.text.borrow_mut().set_focus(false)
196-
},
199+
}
197200
ActiveWidget::SearchBox => {
198201
self.table.borrow_mut().set_focus(false);
199202
self.search.borrow_mut().set_focus(true);
200203
self.text.borrow_mut().set_focus(false)
201-
},
204+
}
202205
ActiveWidget::InfoView => {
203206
self.table.borrow_mut().set_focus(false);
204207
self.search.borrow_mut().set_focus(false);
@@ -211,37 +214,40 @@ impl App {
211214
}
212215

213216
fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
214-
215217
let rects = Layout::default()
216218
.direction(Direction::Vertical)
217-
.constraints(
218-
vec![
219-
Constraint::Min(1),
220-
Constraint::Length(1),
221-
]
222-
)
219+
.constraints(vec![Constraint::Min(1), Constraint::Length(1)])
223220
.split(f.size());
224221

225222
let keys_rect = rects[1];
226223
let rects = Layout::default()
227224
.direction(Direction::Vertical)
228-
.constraints(
229-
vec![
230-
Constraint::Length(if app.search.borrow().visible() { 3 } else { 0 }),
231-
Constraint::Percentage(60),
232-
Constraint::Percentage(40),
233-
],
234-
)
225+
.constraints(vec![
226+
Constraint::Length(if app.search.borrow().visible() { 3 } else { 0 }),
227+
Constraint::Percentage(60),
228+
Constraint::Percentage(40),
229+
])
235230
.split(rects[0]);
236231

237-
if rects[0].width != app.search.borrow().width() || rects[0].height != app.search.borrow().height() {
238-
app.search.borrow_mut().resize(rects[0].width, rects[0].height);
232+
if rects[0].width != app.search.borrow().width()
233+
|| rects[0].height != app.search.borrow().height()
234+
{
235+
app.search
236+
.borrow_mut()
237+
.resize(rects[0].width, rects[0].height);
239238
}
240-
if rects[1].width != app.table.borrow().width() || rects[1].height != app.table.borrow().height() {
241-
app.table.borrow_mut().resize(rects[1].width, rects[1].height);
239+
if rects[1].width != app.table.borrow().width()
240+
|| rects[1].height != app.table.borrow().height()
241+
{
242+
app.table
243+
.borrow_mut()
244+
.resize(rects[1].width, rects[1].height);
242245
}
243-
if rects[2].width != app.text.borrow().width() || rects[2].height != app.text.borrow().height() {
244-
app.text.borrow_mut().resize(rects[2].width, rects[2].height);
246+
if rects[2].width != app.text.borrow().width() || rects[2].height != app.text.borrow().height()
247+
{
248+
app.text
249+
.borrow_mut()
250+
.resize(rects[2].width, rects[2].height);
245251
}
246252

247253
app.prev_size = (f.size().width, f.size().height);
@@ -256,15 +262,11 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
256262
Span::styled("Ctrl+Q", Style::default().fg(Color::White)),
257263
Span::raw(" "),
258264
Span::styled("Quit", Style::default().fg(Color::LightCyan)),
259-
260265
Span::raw(" | "),
261-
262266
Span::styled("Ctrl+F", Style::default().fg(Color::White)),
263267
Span::raw(" "),
264268
Span::styled("Search", Style::default().fg(Color::LightCyan)),
265-
266269
Span::raw(" | "),
267-
268270
Span::styled("Tab", Style::default().fg(Color::White)),
269271
Span::raw(" "),
270272
Span::styled("Next widget", Style::default().fg(Color::LightCyan)),
@@ -277,38 +279,32 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
277279
Span::styled("PageUp", Style::default().fg(Color::White)),
278280
Span::raw(" "),
279281
Span::styled("Go to begin", Style::default().fg(Color::LightCyan)),
280-
281282
Span::raw(" | "),
282283
Span::styled("PageDown", Style::default().fg(Color::White)),
283284
Span::raw(" "),
284285
Span::styled("Go to end", Style::default().fg(Color::LightCyan)),
285286
]);
286-
},
287-
ActiveWidget::SearchBox => {
288-
common_keys.extend_from_slice(&[
289-
Span::raw(" | "),
290-
Span::styled("Ctrl-Bckspc", Style::default().fg(Color::White)),
291-
Span::raw(" "),
292-
Span::styled("Clear", Style::default().fg(Color::LightCyan)),
293-
])
294-
},
287+
}
288+
ActiveWidget::SearchBox => common_keys.extend_from_slice(&[
289+
Span::raw(" | "),
290+
Span::styled("Ctrl-Bckspc", Style::default().fg(Color::White)),
291+
Span::raw(" "),
292+
Span::styled("Clear", Style::default().fg(Color::LightCyan)),
293+
]),
295294
ActiveWidget::InfoView => {
296295
common_keys.extend_from_slice(&[
297296
Span::raw(" | "),
298297
Span::styled("C", Style::default().fg(Color::White)),
299298
Span::raw(" "),
300299
Span::styled("Copy", Style::default().fg(Color::LightCyan)),
301-
302300
Span::raw(" | "),
303301
Span::styled("F", Style::default().fg(Color::White)),
304302
Span::raw(" "),
305303
Span::styled("Add to filter", Style::default().fg(Color::LightCyan)),
306-
307304
Span::raw(" | "),
308305
Span::styled("PageUp", Style::default().fg(Color::White)),
309306
Span::raw(" "),
310307
Span::styled("Go to begin", Style::default().fg(Color::LightCyan)),
311-
312308
Span::raw(" | "),
313309
Span::styled("PageDown", Style::default().fg(Color::White)),
314310
Span::raw(" "),
@@ -317,5 +313,8 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
317313
}
318314
};
319315

320-
f.render_widget(Paragraph::new(Text::from(Spans::from(common_keys))), keys_rect)
316+
f.render_widget(
317+
Paragraph::new(Text::from(Spans::from(common_keys))),
318+
keys_rect,
319+
)
321320
}

src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ mod util;
77
/// 1. Добить запрос с разными типами
88
/// 2. Индексация по полям
99
/// 3. Читать файлы и запоминать только байты конкретных данных
10-
11-
1210
use crate::parser::LogParser;
1311
use app::App;
1412
use clap::Parser;
@@ -20,9 +18,8 @@ use crossterm::{
2018
use std::error::Error;
2119
use tui::{backend::CrosstermBackend, Terminal};
2220

23-
24-
use parser::logdata::LogCollection;
2521
use crate::util::parse_date;
22+
use parser::logdata::LogCollection;
2623

2724
#[derive(Parser, Debug)]
2825
#[clap(author, version, about, long_about = None, verbatim_doc_comment)]

0 commit comments

Comments
 (0)