set envvars
This commit is contained in:
commit
3963fc50c3
9 changed files with 3248 additions and 0 deletions
166
src/tui/log_viewer.rs
Normal file
166
src/tui/log_viewer.rs
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
use std::{collections::HashMap, mem, rc::Rc};
|
||||
|
||||
use crate::tui::{
|
||||
model::LogEntry,
|
||||
reader::{FilterAdapter, LogfileReader},
|
||||
};
|
||||
use tui_widget_list::ListState;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct LogView {
|
||||
first_item: usize,
|
||||
selected: usize,
|
||||
}
|
||||
|
||||
pub struct LogViewer {
|
||||
stack: Vec<LogView>,
|
||||
curr: LogView,
|
||||
cache: HashMap<Vec<usize>, LogView>,
|
||||
|
||||
pub last_height: usize,
|
||||
pub footer_selected: bool,
|
||||
pub footer_list: ListState,
|
||||
}
|
||||
|
||||
impl LogViewer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
stack: Vec::new(),
|
||||
curr: LogView::default(),
|
||||
cache: HashMap::new(),
|
||||
footer_list: ListState::default(),
|
||||
footer_selected: false,
|
||||
last_height: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_num_items(&mut self, num_visible_items: usize) {
|
||||
while self.curr.selected >= self.curr.first_item + num_visible_items {
|
||||
self.curr.first_item += 1;
|
||||
}
|
||||
self.last_height = num_visible_items;
|
||||
}
|
||||
|
||||
pub fn footer_fields(&self, file: &mut LogfileReader) -> Vec<(String, serde_json::Value)> {
|
||||
if let Some(selected) = self.selected(file) {
|
||||
selected.all_fields().fields.into_iter().collect::<Vec<_>>()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn items(
|
||||
&self,
|
||||
file: &mut LogfileReader,
|
||||
max: usize,
|
||||
) -> Option<(Vec<Rc<LogEntry>>, usize, usize)> {
|
||||
let items: Vec<_> = if self.stack.is_empty() {
|
||||
file.iter_from(self.curr.first_item).take(max).collect()
|
||||
} else {
|
||||
let mut stack = self.stack.iter();
|
||||
let first = stack.next().unwrap();
|
||||
let mut curr_log_entry = file.iter_from(first.selected).next()?;
|
||||
for elem in stack {
|
||||
curr_log_entry = curr_log_entry.get(elem.selected)?;
|
||||
}
|
||||
|
||||
match curr_log_entry.as_ref() {
|
||||
LogEntry::Single { .. } => return None,
|
||||
LogEntry::Sub { sub_entries, .. } => {
|
||||
FilterAdapter::new(file, &sub_entries[self.curr.first_item..])
|
||||
.take(max)
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Some((items, self.curr.first_item, self.curr.selected))
|
||||
}
|
||||
|
||||
pub fn selected(&self, file: &mut LogfileReader) -> Option<Rc<LogEntry>> {
|
||||
self.items(file, self.curr.selected - self.curr.first_item + 1)?
|
||||
.0
|
||||
.get(self.curr.selected - self.curr.first_item)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn update_footer_select(&mut self) {
|
||||
self.footer_list.select(Some(0));
|
||||
}
|
||||
|
||||
pub fn prev(&mut self) {
|
||||
if self.footer_selected {
|
||||
self.footer_list.previous();
|
||||
} else {
|
||||
self.curr.selected = self.curr.selected.saturating_sub(1);
|
||||
self.curr.first_item = self.curr.first_item.min(self.curr.selected);
|
||||
self.update_footer_select();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next(&mut self) {
|
||||
if self.footer_selected {
|
||||
self.footer_list.next();
|
||||
} else {
|
||||
self.curr.selected += 1;
|
||||
self.update_footer_select();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn page_down(&mut self) {
|
||||
self.curr.selected += self.last_height;
|
||||
self.footer_selected = false;
|
||||
self.update_footer_select();
|
||||
}
|
||||
|
||||
pub fn page_up(&mut self) {
|
||||
self.curr.selected = self.curr.selected.saturating_sub(self.last_height);
|
||||
self.curr.first_item = self.curr.first_item.min(self.curr.selected);
|
||||
self.footer_selected = false;
|
||||
self.update_footer_select();
|
||||
}
|
||||
|
||||
pub fn home(&mut self) {
|
||||
if self.footer_selected {
|
||||
self.footer_list.select(Some(0));
|
||||
} else {
|
||||
self.curr.selected = 0;
|
||||
self.curr.first_item = 0;
|
||||
self.update_footer_select();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path(&self) -> Vec<usize> {
|
||||
self.stack.iter().map(|i| i.selected).collect()
|
||||
}
|
||||
|
||||
pub fn back(&mut self) {
|
||||
self.cache.insert(self.path(), self.curr);
|
||||
self.curr = self.stack.pop().unwrap_or_default();
|
||||
self.footer_selected = false;
|
||||
self.update_footer_select();
|
||||
}
|
||||
|
||||
pub fn switch_focus(&mut self) {
|
||||
self.footer_selected = !self.footer_selected;
|
||||
}
|
||||
|
||||
pub fn enter(&mut self, file: &mut LogfileReader) {
|
||||
if !self.footer_selected {
|
||||
let Some(s) = self.selected(file) else {
|
||||
return;
|
||||
};
|
||||
if let LogEntry::Single { .. } = s.as_ref() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.stack
|
||||
.push(mem::replace(&mut self.curr, LogView::default()));
|
||||
if let Some(cached_view) = self.cache.get(&self.path()) {
|
||||
self.curr = *cached_view;
|
||||
}
|
||||
self.update_footer_select();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue