use kas::event::EventCx;
use kas_widgets::edit::{EditGuard, Editor};
use std::fmt::Debug;
pub trait FilterValue: Default + 'static {
type Value: std::fmt::Debug;
fn set_filter(&mut self, value: Self::Value);
}
pub trait Filter<T: ?Sized>: FilterValue {
fn matches(&self, item: &T) -> bool;
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ContainsString(String);
impl ContainsString {
pub fn new() -> Self {
ContainsString(String::new())
}
}
impl FilterValue for ContainsString {
type Value = String;
fn set_filter(&mut self, value: String) {
self.0 = value;
}
}
impl Filter<str> for ContainsString {
fn matches(&self, item: &str) -> bool {
item.contains(&self.0)
}
}
impl Filter<String> for ContainsString {
fn matches(&self, item: &String) -> bool {
Filter::<str>::matches(self, item.as_str())
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ContainsCaseInsensitive(String);
impl ContainsCaseInsensitive {
pub fn new() -> Self {
ContainsCaseInsensitive(String::new())
}
}
impl FilterValue for ContainsCaseInsensitive {
type Value = String;
fn set_filter(&mut self, value: String) {
self.0 = value.to_uppercase();
}
}
impl Filter<str> for ContainsCaseInsensitive {
fn matches(&self, item: &str) -> bool {
item.to_string().to_uppercase().contains(&self.0)
}
}
impl Filter<String> for ContainsCaseInsensitive {
fn matches(&self, item: &String) -> bool {
Filter::<str>::matches(self, item.as_str())
}
}
#[derive(Debug, Default)]
pub struct SetFilter<T: Debug>(pub T);
pub struct KeystrokeGuard;
impl EditGuard for KeystrokeGuard {
type Data = ();
fn edit(&mut self, edit: &mut Editor, cx: &mut EventCx, _: &Self::Data) {
cx.push(SetFilter(edit.as_str().to_string()));
}
}
pub struct AflGuard;
impl EditGuard for AflGuard {
type Data = ();
#[inline]
fn focus_lost(&mut self, edit: &mut Editor, cx: &mut EventCx, _: &Self::Data) {
cx.push(SetFilter(edit.as_str().to_string()));
}
}