modal
This commit is contained in:
parent
d989f6e31e
commit
cc4ecf40d7
6 changed files with 402 additions and 331 deletions
|
|
@ -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 {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue