This commit is contained in:
Jana Dönszelmann 2026-02-25 09:21:50 +01:00
parent d989f6e31e
commit cc4ecf40d7
No known key found for this signature in database
6 changed files with 402 additions and 331 deletions

View file

@ -1,51 +1,77 @@
use crate::tui::model::LogEntry;
use regex::bytes::Regex;
#[derive(Clone)]
pub enum WipMatcher {
Field {
name: Option<String>,
value: Option<serde_json::Value>,
},
Specific {
hash: Option<u64>,
},
use crate::tui::{
log_viewer::{FieldMatcher, InputTarget, LogViewer},
model::{LogEntry, pretty_print_value},
};
pub enum MatcherValue {
Exact(String),
Regex(Regex),
Prefix(String),
Contains(String),
}
impl WipMatcher {
fn validate(&self) -> Option<Matcher> {
impl MatcherValue {
pub fn from_field_matcher(fm: FieldMatcher, selected: Option<String>) -> Option<Self> {
match fm {
FieldMatcher::EqualTo => Some(Self::Exact(selected?)),
FieldMatcher::Prefix(p) => Some(Self::Prefix(p)),
FieldMatcher::Regex(r) => Some(Self::Regex(Regex::new(&r).ok()?)),
FieldMatcher::Contains(c) => Some(Self::Contains(c)),
}
}
pub fn matches(&self, v: &str) -> bool {
match self {
WipMatcher::Field {
name: Some(name),
value: Some(value),
} => Some(Matcher::Field {
name: name.clone(),
value: value.clone(),
}),
WipMatcher::Specific { hash } => Some(Matcher::Specific { hash: (*hash)? }),
_ => None,
MatcherValue::Exact(e) => e == v,
MatcherValue::Regex(regex) => regex.is_match(v.as_bytes()),
MatcherValue::Prefix(p) => v.starts_with(p),
MatcherValue::Contains(c) => v.contains(c),
}
}
}
pub enum Matcher {
Field {
name: String,
value: serde_json::Value,
},
Specific {
hash: u64,
},
Field { name: String, value: MatcherValue },
Message { value: MatcherValue },
Specific { hash: u64 },
}
impl Matcher {
pub fn matches(&self, entry: &LogEntry) -> bool {
match self {
Matcher::Specific { hash } => entry.hash() == *hash,
Matcher::Field { name, value } => entry
.all_fields()
.fields
.get(name)
.is_some_and(|v| v == value),
Matcher::Specific { hash } => entry.hash() == *hash,
.is_some_and(|v| value.matches(&pretty_print_value(&v))),
Matcher::Message { value } => {
entry.message_or_name().is_some_and(|v| value.matches(&v))
}
}
}
pub fn from_input(target: InputTarget, lv: &LogViewer) -> Option<Self> {
match target {
InputTarget::Fields(fm) => {
let value = lv.footer_fields().get(lv.footer_list.selected?)?.clone();
Some(Self::Field {
name: value.0,
value: MatcherValue::from_field_matcher(fm?, Some(value.1.to_string()))?,
})
}
InputTarget::Text(fm) => Some(Self::Message {
value: MatcherValue::from_field_matcher(
fm,
lv.selected().and_then(|(i, _)| i.message_or_name()),
)?,
}),
InputTarget::This => lv
.selected()
.map(|(i, _)| Self::Specific { hash: i.hash() }),
InputTarget::Surround => todo!(),
}
}
}
@ -69,99 +95,3 @@ impl Filter {
}
}
}
#[derive(Clone)]
pub struct WipFilter {
pub matcher: Option<WipMatcher>,
pub kind: Option<FilterKind>,
pub selection: FilterSelection,
}
impl WipFilter {
pub fn validate(&self) -> Option<Filter> {
let Self {
matcher,
kind,
selection: _,
} = self;
let Some(matcher) = matcher else { return None };
Some(Filter {
matcher: matcher.validate()?,
kind: kind.clone()?,
})
}
pub fn clear(&mut self) {
match self.selection {
FilterSelection::Kind => self.kind = None,
FilterSelection::MatcherKind => {}
FilterSelection::Matcher => {}
FilterSelection::Confirm => {}
}
}
pub fn right(&mut self) {
match self.selection {
FilterSelection::Kind => {
self.kind = Some(match self.kind {
None => FilterKind::Inline,
Some(FilterKind::Inline) => FilterKind::Remove,
Some(FilterKind::Remove) => FilterKind::Inline,
})
}
FilterSelection::MatcherKind => {}
FilterSelection::Matcher => {}
FilterSelection::Confirm => {}
}
}
pub fn left(&mut self) {
match self.selection {
FilterSelection::Kind => {
self.kind = Some(match self.kind {
None => FilterKind::Remove,
Some(FilterKind::Remove) => FilterKind::Inline,
Some(FilterKind::Inline) => FilterKind::Inline,
})
}
FilterSelection::MatcherKind => {}
FilterSelection::Matcher => {}
FilterSelection::Confirm => {}
}
}
}
#[derive(Clone, Copy)]
pub enum FilterSelection {
Kind,
MatcherKind,
Matcher,
Confirm,
}
impl FilterSelection {
pub fn next(&mut self) {
*self = match *self {
Self::Kind => Self::MatcherKind,
Self::MatcherKind => Self::Matcher,
Self::Matcher => Self::Confirm,
Self::Confirm => Self::Confirm,
};
}
pub fn prev(&mut self) {
*self = match self {
Self::Kind => Self::Kind,
Self::MatcherKind => Self::Kind,
Self::Matcher => Self::MatcherKind,
Self::Confirm => Self::Matcher,
};
}
}
#[derive(Clone, Copy)]
pub enum FieldMatcherSelection {
Field,
Value,
}
impl FieldMatcherSelection {}