use crate::Client;
use ad_event::{FsysEvent, Kind, Source};
use std::io;
#[derive(Debug)]
pub enum Outcome {
Passthrough,
Handled,
PassthroughAndExit,
Exit,
}
#[allow(unused_variables)]
pub trait EventFilter {
fn handle_insert(
&mut self,
src: Source,
from: usize,
to: usize,
txt: &str,
client: &mut Client,
) -> io::Result<Outcome> {
Ok(Outcome::Handled)
}
fn handle_delete(
&mut self,
src: Source,
from: usize,
to: usize,
client: &mut Client,
) -> io::Result<Outcome> {
Ok(Outcome::Handled)
}
fn handle_load(
&mut self,
src: Source,
from: usize,
to: usize,
txt: &str,
client: &mut Client,
) -> io::Result<Outcome> {
Ok(Outcome::Passthrough)
}
fn handle_execute(
&mut self,
src: Source,
from: usize,
to: usize,
txt: &str,
client: &mut Client,
) -> io::Result<Outcome> {
Ok(Outcome::Passthrough)
}
}
pub(crate) fn run_filter<F>(buffer: &str, mut filter: F, client: &mut Client) -> io::Result<()>
where
F: EventFilter,
{
for line in client.event_lines(buffer)? {
let evt = FsysEvent::try_from_str(&line).map_err(io::Error::other)?;
let outcome = match evt.kind {
Kind::LoadBody => {
filter.handle_load(evt.source, evt.ch_from, evt.ch_to, &evt.txt, client)?
}
Kind::ExecuteBody => {
filter.handle_execute(evt.source, evt.ch_from, evt.ch_to, &evt.txt, client)?
}
Kind::InsertBody => {
filter.handle_insert(evt.source, evt.ch_from, evt.ch_to, &evt.txt, client)?
}
Kind::DeleteBody => filter.handle_delete(evt.source, evt.ch_from, evt.ch_to, client)?,
_ => Outcome::Passthrough,
};
match outcome {
Outcome::Handled => (),
Outcome::Passthrough => client.write_event(buffer, &evt.as_event_file_line())?,
Outcome::PassthroughAndExit => {
client.write_event(buffer, &evt.as_event_file_line())?;
return Ok(());
}
Outcome::Exit => return Ok(()),
}
}
Ok(())
}