Add methods to configure tagger filter
This commit is contained in:
parent
4fda3c477b
commit
f3c74bd151
|
@ -11,6 +11,7 @@ use crate::event::{Event, Tag};
|
|||
use crate::filter::Filterer;
|
||||
|
||||
mod parse;
|
||||
pub mod swaplock;
|
||||
|
||||
pub struct TaggedFilterer {
|
||||
/// The directory the project is in, its "root".
|
||||
|
@ -102,6 +103,14 @@ pub struct Filter {
|
|||
}
|
||||
|
||||
impl TaggedFilterer {
|
||||
pub fn new(root: impl Into<PathBuf>, workdir: impl Into<PathBuf>) -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
root: root.into(),
|
||||
workdir: workdir.into(),
|
||||
filters: swaplock::SwapLock::new(HashMap::new()),
|
||||
})
|
||||
}
|
||||
|
||||
fn match_tag(&self, filter: &Filter, tag: &Tag) -> Result<Option<bool>, RuntimeError> {
|
||||
trace!(?tag, matcher=?filter.on, "matching filter to tag");
|
||||
match (tag, filter.on) {
|
||||
|
@ -124,6 +133,44 @@ impl TaggedFilterer {
|
|||
.map(Some)
|
||||
}
|
||||
|
||||
pub async fn add_filter(&self, filter: Filter) -> Result<(), RuntimeError> {
|
||||
debug!(?filter, "adding filter to filterer");
|
||||
self.filters
|
||||
.change(|filters| {
|
||||
filters.entry(filter.on).or_default().push(filter);
|
||||
})
|
||||
.await
|
||||
.map_err(|err| RuntimeError::FilterChange { action: "add", err })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_filter(&self, filter: &Filter) -> Result<(), RuntimeError> {
|
||||
debug!(?filter, "removing filter from filterer");
|
||||
self.filters
|
||||
.change(|filters| {
|
||||
filters
|
||||
.entry(filter.on)
|
||||
.or_default()
|
||||
.retain(|f| f != filter);
|
||||
})
|
||||
.await
|
||||
.map_err(|err| RuntimeError::FilterChange {
|
||||
action: "remove",
|
||||
err,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn clear_filters(&self) -> Result<(), RuntimeError> {
|
||||
debug!("removing all filters from filterer");
|
||||
self.filters
|
||||
.replace(Default::default())
|
||||
.await
|
||||
.map_err(|err| RuntimeError::FilterChange {
|
||||
action: "clear all",
|
||||
err,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
use std::fmt;
|
||||
|
||||
use tokio::sync::watch::{channel, error::SendError, Receiver, Ref, Sender};
|
||||
|
||||
pub struct SwapLock<T: Clone> {
|
||||
r: Receiver<T>,
|
||||
s: Sender<T>,
|
||||
}
|
||||
|
||||
impl<T> SwapLock<T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
pub fn new(inner: T) -> Self {
|
||||
let (s, r) = channel(inner);
|
||||
Self { r, s }
|
||||
}
|
||||
|
||||
pub fn borrow(&self) -> Ref<'_, T> {
|
||||
self.r.borrow()
|
||||
}
|
||||
|
||||
pub async fn change(&self, f: impl FnOnce(&mut T)) -> Result<(), SendError<T>> {
|
||||
let mut new = self.r.borrow().clone();
|
||||
f(&mut new);
|
||||
self.s.send(new)
|
||||
}
|
||||
|
||||
pub async fn replace(&self, new: T) -> Result<(), SendError<T>> {
|
||||
self.s.send(new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for SwapLock<T>
|
||||
where
|
||||
T: fmt::Debug + Clone,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
f.debug_struct("SwapLock")
|
||||
.field("(watch)", &self.r)
|
||||
.finish()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue