mod anymap;
pub mod value;
pub mod extractor;
pub mod layer;
pub mod output;
use crate::Operator;
use alloc::boxed::Box;
use self::layer::{
cache::CacheOperator,
data::AddDataOperator,
insert::{InsertDataOperator, InsertOperator, InsertWithDataOperator},
inspect::InspectOperator,
optional::Either,
then::ThenOperator,
};
pub use self::{
anymap::{Context, Map},
extractor::{Data, Env, In, Prev},
layer::{
cache::Cache,
data::AddData,
insert::{Insert, InsertData, InsertWithData},
inspect::Inspect,
layer_fn,
optional::OptionalLayer,
then::Then,
BoxLayer, Layer,
},
output::{insert_and_output, insert_env_and_output, output},
value::{input, Value, ValueRef},
};
pub trait ContextOperator<In> {
type Out;
fn next(&mut self, input: Value<In>) -> Value<Self::Out>;
}
impl<In, P, Out> ContextOperator<In> for P
where
P: Operator<Value<In>, Output = Value<Out>>,
{
type Out = Out;
#[inline]
fn next(&mut self, input: Value<In>) -> Value<Out> {
self.next(input)
}
}
pub type BoxContextOperator<In, Out> = Box<dyn ContextOperator<In, Out = Out> + Send>;
impl<In, Out> ContextOperator<In> for BoxContextOperator<In, Out> {
type Out = Out;
fn next(&mut self, input: Value<In>) -> Value<Self::Out> {
self.as_mut().next(input)
}
}
pub trait ContextOperatorExt<In>: ContextOperator<In> {
fn boxed(self) -> BoxContextOperator<In, Self::Out>
where
Self: Send + Sized + 'static,
{
Box::new(self)
}
fn with<L>(self, layer: L) -> L::Operator
where
L: Layer<In, Self>,
Self: Sized,
{
layer.layer(self)
}
#[inline]
fn finish(self) -> ContextedOperator<Self>
where
Self: Sized,
{
self.finish_with_data(Map::default())
}
#[inline]
fn finish_with_data(self, data: Map) -> ContextedOperator<Self>
where
Self: Sized,
{
ContextedOperator(self, data)
}
fn cache(self, length: usize) -> CacheOperator<Self>
where
Self: Sized,
{
self.with(Cache::with_length(
length.try_into().expect("`length` cannot be 0"),
))
}
fn insert_env<R, Out>(self, f: impl Fn() -> R) -> InsertOperator<Self, R>
where
R: for<'a> RefOperator<'a, In, Output = Out>,
Out: Send + Sync + 'static,
Self: Sized,
{
self.with(Insert(f))
}
fn insert_env_if<R, Out>(
self,
enable: bool,
f: impl Fn() -> R,
) -> Either<InsertOperator<Self, R>, Self>
where
R: for<'a> RefOperator<'a, In, Output = Out>,
Out: Send + Sync + 'static,
Self: Sized,
{
self.with_if(if enable { Some(Insert(f)) } else { None })
}
fn insert_data<R, Out>(self, f: impl Fn() -> R) -> InsertDataOperator<Self, R>
where
R: for<'a> RefOperator<'a, In, Output = Option<Out>>,
Out: Send + Sync + 'static,
Self: Sized,
{
self.with(InsertData(f))
}
fn insert_data_if<R, Out>(
self,
enable: bool,
f: impl Fn() -> R,
) -> Either<InsertDataOperator<Self, R>, Self>
where
R: for<'a> RefOperator<'a, In, Output = Option<Out>>,
Out: Send + Sync + 'static,
Self: Sized,
{
self.with_if(if enable { Some(InsertData(f)) } else { None })
}
fn insert<R, Env, Data>(self, f: impl Fn() -> R) -> InsertWithDataOperator<Self, R>
where
R: for<'a> RefOperator<'a, In, Output = (Env, Option<Data>)>,
Env: Send + Sync + 'static,
Data: Send + Sync + 'static,
Self: Sized,
{
self.with(InsertWithData(f))
}
fn insert_if<R, Env, Data>(
self,
enable: bool,
f: impl Fn() -> R,
) -> Either<InsertWithDataOperator<Self, R>, Self>
where
R: for<'a> RefOperator<'a, In, Output = (Env, Option<Data>)>,
Env: Send + Sync + 'static,
Data: Send + Sync + 'static,
Self: Sized,
{
self.with_if(if enable {
Some(InsertWithData(f))
} else {
None
})
}
fn inspect<F>(self, f: F) -> InspectOperator<Self, F>
where
F: Fn(&In, &Context) + Clone,
Self: Sized,
{
self.with(Inspect(f))
}
fn provide<D>(self, data: D) -> AddDataOperator<D, Self>
where
D: Clone + Send + Sync + 'static,
Self: Sized,
{
self.with(AddData::with_data(data))
}
fn provide_if<D>(self, data: Option<D>) -> Either<AddDataOperator<D, Self>, Self>
where
D: Clone + Send + Sync + 'static,
Self: Sized,
{
self.with_if(data.map(AddData::with_data))
}
fn provide_with<D>(
self,
provider: impl Fn() -> Option<D> + Send + Sync + 'static,
) -> AddDataOperator<D, Self>
where
D: Send + Sync + 'static,
Self: Sized,
{
self.with(AddData::new(provider))
}
fn provide_with_if<D>(
self,
enable: bool,
provider: impl Fn() -> Option<D> + Send + Sync + 'static,
) -> Either<AddDataOperator<D, Self>, Self>
where
D: Send + Sync + 'static,
Self: Sized,
{
self.with_if(if enable {
Some(AddData::new(provider))
} else {
None
})
}
#[allow(clippy::wrong_self_convention)]
#[deprecated(note = "use `data_from_context` instead")]
fn from_context<D>(self) -> AddDataOperator<D, Self>
where
D: Send + Sync + 'static,
Self: Sized,
{
self.with(AddData::<D>::from_context())
}
fn data_from_context<D>(self) -> AddDataOperator<D, Self>
where
D: Send + Sync + 'static,
Self: Sized,
{
self.with(AddData::<D>::from_context())
}
fn then_with<Out, F, Builder>(self, builder: Builder) -> ThenOperator<Self, F>
where
F: FnMut(Self::Out, &Context) -> Out + Clone,
Builder: Fn() -> F,
Self: Sized,
{
self.with(Then(builder))
}
fn with_if<L>(self, layer: Option<L>) -> Either<L::Operator, Self>
where
L: Layer<In, Self>,
L::Operator: ContextOperator<In, Out = Self::Out>,
Self: Sized,
{
self.with(OptionalLayer(layer))
}
}
impl<T, P> ContextOperatorExt<T> for P where P: ContextOperator<T> {}
#[derive(Debug, Default)]
pub struct ContextedOperator<P>(P, Map);
impl<In, P> Operator<In> for ContextedOperator<P>
where
P: ContextOperator<In>,
{
type Output = P::Out;
#[inline]
fn next(&mut self, input: In) -> Self::Output {
let mut value = self
.0
.next(Value::with_data(input, core::mem::take(&mut self.1)));
core::mem::swap(&mut self.1, value.context_mut().data_mut());
value.into_inner()
}
}
pub trait RefOperator<'a, In> {
type Output;
fn next(&mut self, input: ValueRef<'a, In>) -> Self::Output;
}
impl<'a, In, P> RefOperator<'a, In> for P
where
P: Operator<ValueRef<'a, In>>,
In: 'a,
{
type Output = P::Output;
#[inline]
fn next(&mut self, input: ValueRef<'a, In>) -> Self::Output {
self.next(input)
}
}