use crate::component::MetaResponse;
use crate::{App, BoxFuture, Response};
use http::Extensions;
macro_rules! builder {
($f:ident, $var: ident, $hd: ident, $ref:ident, $ret: ty, $bd: expr, $($item:ty,)*) => {
#[doc = "Set the `"]
#[doc = stringify!($hd)]
#[doc = "` of `PipeLine`, if not called, the default value is `None`"]
#[doc = ""]
#[doc = "# Examples"]
#[doc = ""]
#[doc = "```rust"]
#[doc = "# use dyer::pipeline::*;"]
#[doc = concat!("async fn ", stringify!($hd), "(", stringify!($(_: &mut Vec<$item>, )*), "_: &mut App<E>) {}" )]
#[doc = concat!("let pipeline = ", stringify!($bd))]
#[doc = concat!(" ", stringify!(.$f),"(&", stringify!($hd), ")" ) ]
#[doc = " .build(\"marker\".into());"]
#[doc = stringify!(assert!(pipeline.$hd.is_some()) )]
#[doc = "```"]
pub fn $f(
mut self,
$var: &'pl dyn for<'a> Fn($(Vec<$item>,)* &'a mut App<E>) -> BoxFuture<'a, $ret>,
) -> Self
{
self.$hd = Some($var );
self
}
#[doc = "Get the shared reference of `"]
#[doc = stringify!($hd)]
#[doc = "` of `PipeLine`, if not set before, `None` is returned"]
#[doc = ""]
#[doc = "# Examples"]
#[doc = ""]
#[doc = "```rust"]
#[doc = "# use dyer::pipeline::*;"]
#[doc = concat!("async fn ", stringify!($hd), "(", stringify!($(_: &mut Vec<$item>, )*), "_: &mut App<E>) {}" )]
#[doc = concat!("let pipeline = ", stringify!($bd))]
#[doc = concat!(" ", stringify!(.$f),"(&", stringify!($hd), ")" ) ]
#[doc = " .build(\"marker\".into());"]
#[doc = stringify!(assert_eq!(pipeline.$ref(), Some($hd)) )]
#[doc = "```"]
pub fn $ref(&self) ->
Option<&'pl dyn for<'a> Fn($(Vec<$item>,)* &'a mut App<E>) -> BoxFuture<'a, $ret>>
{
self.$hd
}
};
}
pub struct PipeLine<'pl, E, C> {
pub(crate) initializer: Option<&'pl dyn for<'a> Fn(&'a mut App<E>) -> BoxFuture<'a, Option<C>>>,
pub(crate) disposer: Option<&'pl dyn for<'a> Fn(&'a mut App<E>) -> BoxFuture<'a, ()>>,
pub(crate) process_entity:
Option<&'pl dyn for<'a> Fn(Vec<E>, &'a mut App<E>) -> BoxFuture<'a, ()>>,
pub(crate) process_yerr: Option<
&'pl dyn for<'a> Fn(
Vec<Result<Response, MetaResponse>>,
&'a mut App<E>,
) -> BoxFuture<'a, ()>,
>,
pub marker: String,
pub rank: i16,
pub extensions: Extensions,
}
impl<'pl, E, C> PipeLine<'pl, E, C> {
pub fn builder() -> PipeLineBuilder<'pl, E, C> {
PipeLineBuilder::new()
}
pub fn rank(&self) -> i16 {
self.rank
}
pub fn rank_mut(&mut self) -> &mut i16 {
&mut self.rank
}
pub fn extensions_mut(&mut self) -> &mut Extensions {
&mut self.extensions
}
pub fn extensions(&self) -> &Extensions {
&self.extensions
}
builder!(
initializer_mut,
initials,
initializer,
initializer,
Option<C>,
PipeLines::builder(),
);
builder!(
disposer_mut,
dispose,
disposer,
disposer,
(),
PipeLines::builder(),
);
builder!(
entity_mut,
entity,
process_entity,
entity,
(),
PipeLines::builder(),
E,
);
builder!(
yerr_mut,
yerr,
process_yerr,
yerr,
(),
PipeLines::builder(),
Result<Response, MetaResponse>,
);
}
pub struct PipeLineBuilder<'pl, E, C>
where
C: 'static,
{
initializer: Option<&'pl dyn for<'a> Fn(&'a mut App<E>) -> BoxFuture<'a, Option<C>>>,
disposer: Option<&'pl dyn for<'a> Fn(&'a mut App<E>) -> BoxFuture<'a, ()>>,
process_entity: Option<&'pl dyn for<'a> Fn(Vec<E>, &'a mut App<E>) -> BoxFuture<'a, ()>>,
process_yerr: Option<
&'pl dyn for<'a> Fn(
Vec<Result<Response, MetaResponse>>,
&'a mut App<E>,
) -> BoxFuture<'a, ()>,
>,
rank: i16,
extensions: Extensions,
}
impl<'pl, E, C> PipeLineBuilder<'pl, E, C> {
pub fn new() -> Self {
Self {
initializer: None,
process_entity: None,
process_yerr: None,
disposer: None,
rank: 0,
extensions: Extensions::new(),
}
}
pub fn build<T: Into<String>>(self, marker: T) -> PipeLine<'pl, E, C> {
let all = self.initializer.is_some()
|| self.disposer.is_some()
|| self.process_yerr.is_some()
|| self.process_entity.is_some();
assert!(all, "None of pipeline has been specified");
PipeLine {
initializer: self.initializer,
disposer: self.disposer,
process_entity: self.process_entity,
process_yerr: self.process_yerr,
marker: marker.into(),
rank: self.rank,
extensions: self.extensions,
}
}
pub fn extensions<S>(mut self, extensions: S) -> Self
where
S: std::any::Any + Send + Sync + 'static,
{
self.extensions.insert(extensions);
self
}
pub fn extensions_ref(&self) -> &Extensions {
&self.extensions
}
pub fn rank(mut self, rank: i16) -> Self {
self.rank = rank;
self
}
pub fn rank_ref(&self) -> i16 {
self.rank
}
builder!(
initializer,
initials,
initializer,
initializer_ref,
Option<C>,
PipeLines::builder(),
);
builder!(
disposer,
dispose,
disposer,
disposer_ref,
(),
PipeLines::builder(),
);
builder!(
entity,
entity,
process_entity,
entity_ref,
(),
PipeLines::builder(),
E,
);
builder!(
yerr,
yerr,
process_yerr,
yerr_ref,
(),
PipeLines::builder(),
Result<Response, MetaResponse>,
);
}