use std::borrow::Cow;
use super::Context;
use crate::{session::OsProcess, Error, Session};
type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct InteractOptions<C, IF, OF, IA, OA, WA> {
pub(crate) state: C,
pub(crate) input_filter: Option<IF>,
pub(crate) output_filter: Option<OF>,
pub(crate) input_action: Option<IA>,
pub(crate) output_action: Option<OA>,
pub(crate) idle_action: Option<WA>,
}
type DefaultOps<S, I, O, C> = InteractOptions<
C,
NoFilter,
NoFilter,
NoAction<Session<OsProcess, S>, I, O, C>,
NoAction<Session<OsProcess, S>, I, O, C>,
NoAction<Session<OsProcess, S>, I, O, C>,
>;
impl<S, I, O> Default for DefaultOps<S, I, O, ()> {
fn default() -> Self {
Self::new(())
}
}
impl<S, I, O, C> DefaultOps<S, I, O, C> {
pub fn new(state: C) -> Self {
Self {
state,
input_filter: None,
output_filter: None,
input_action: None,
output_action: None,
idle_action: None,
}
}
}
impl<C, IF, OF, IA, OA, WA> InteractOptions<C, IF, OF, IA, OA, WA> {
pub fn get_state(&self) -> &C {
&self.state
}
pub fn get_state_mut(&mut self) -> &mut C {
&mut self.state
}
pub fn into_inner(self) -> C {
self.state
}
pub fn output_filter<F>(self, filter: F) -> InteractOptions<C, IF, F, IA, OA, WA>
where
F: FnMut(&[u8]) -> Result<Cow<'_, [u8]>>,
{
InteractOptions {
input_filter: self.input_filter,
output_filter: Some(filter),
input_action: self.input_action,
output_action: self.output_action,
idle_action: self.idle_action,
state: self.state,
}
}
pub fn input_filter<F>(self, filter: F) -> InteractOptions<C, F, OF, IA, OA, WA>
where
F: FnMut(&[u8]) -> Result<Cow<'_, [u8]>>,
{
InteractOptions {
input_filter: Some(filter),
output_filter: self.output_filter,
input_action: self.input_action,
output_action: self.output_action,
idle_action: self.idle_action,
state: self.state,
}
}
}
impl<S, I, O, C, IF, OF, OA, WA>
InteractOptions<C, IF, OF, NoAction<Session<OsProcess, S>, I, O, C>, OA, WA>
{
pub fn on_input<F>(self, action: F) -> InteractOptions<C, IF, OF, F, OA, WA>
where
F: FnMut(Context<'_, Session<OsProcess, S>, I, O, C>) -> Result<bool>,
{
InteractOptions {
input_filter: self.input_filter,
output_filter: self.output_filter,
input_action: Some(action),
output_action: self.output_action,
idle_action: self.idle_action,
state: self.state,
}
}
}
impl<S, I, O, C, IF, OF, IA, WA>
InteractOptions<C, IF, OF, IA, NoAction<Session<OsProcess, S>, I, O, C>, WA>
{
pub fn on_output<F>(self, action: F) -> InteractOptions<C, IF, OF, IA, F, WA>
where
F: FnMut(Context<'_, Session<OsProcess, S>, I, O, C>) -> Result<bool>,
{
InteractOptions {
input_filter: self.input_filter,
output_filter: self.output_filter,
input_action: self.input_action,
output_action: Some(action),
idle_action: self.idle_action,
state: self.state,
}
}
}
impl<S, I, O, C, IF, OF, IA, OA>
InteractOptions<C, IF, OF, IA, OA, NoAction<Session<OsProcess, S>, I, O, C>>
{
pub fn on_idle<F>(self, action: F) -> InteractOptions<C, IF, OF, IA, OA, F>
where
F: FnMut(Context<'_, Session<OsProcess, S>, I, O, C>) -> Result<bool>,
{
InteractOptions {
input_filter: self.input_filter,
output_filter: self.output_filter,
input_action: self.input_action,
output_action: self.output_action,
idle_action: Some(action),
state: self.state,
}
}
}
pub type NoAction<S, I, O, C> = fn(Context<'_, S, I, O, C>) -> Result<bool>;
pub type NoFilter = fn(&[u8]) -> Result<Cow<'_, [u8]>>;