use comp_cat_rs::effect::io::Io;
use crate::filter::{self, Filter};
use crate::hydrator::{self, Hydrator};
use crate::score::ScoredCandidate;
use crate::scorer::{self, Scorer};
use crate::selector::{self, Budget, Selector};
use crate::side_effect::{self, SideEffect};
use crate::source::Source;
use crate::stage::Stage;
#[must_use]
pub struct UnscoredPipeline<E, Q, I> {
stage: Stage<E, Q, Vec<I>>,
}
impl<E: Send + 'static, Q: Clone + Send + 'static, I: Send + 'static>
UnscoredPipeline<E, Q, I>
{
pub fn hydrate<J: Send + 'static, H>(self, hydrator: H) -> UnscoredPipeline<E, Q, J>
where
H: Hydrator<I, J, E> + Send + Sync + 'static,
{
UnscoredPipeline {
stage: self.stage.then(hydrator::hydrator_stage(hydrator)),
}
}
pub fn filter<F>(self, filter: F) -> Self
where
F: Filter<I, E> + Send + Sync + 'static,
{
UnscoredPipeline {
stage: self.stage.then(filter::filter_stage(filter)),
}
}
pub fn tap<S>(self, effect: S) -> Self
where
S: SideEffect<I, E> + Send + 'static,
{
UnscoredPipeline {
stage: self.stage.then(side_effect::side_effect_stage(effect)),
}
}
pub fn score<S>(self, s: S) -> ScoredPipeline<E, Q, I>
where
S: Scorer<I, E> + Send + Sync + 'static,
{
ScoredPipeline {
stage: self.stage.then(scorer::scorer_stage(s)),
}
}
}
#[must_use]
pub struct ScoredPipeline<E, Q, I> {
stage: Stage<E, Q, Vec<ScoredCandidate<I>>>,
}
impl<E: Send + 'static, Q: Send + 'static, I: Send + 'static> ScoredPipeline<E, Q, I> {
pub fn select<S>(self, s: S, budget: Budget) -> Pipeline<E, Q, I>
where
S: Selector<I, E> + Send + 'static,
{
Pipeline {
stage: self.stage.then(selector::selector_stage(s, budget)),
}
}
}
#[must_use]
pub struct Pipeline<E, Q, I> {
stage: Stage<E, Q, Vec<ScoredCandidate<I>>>,
}
impl<E: Send + 'static, Q: Clone + Send + 'static, I: Send + 'static> Pipeline<E, Q, I> {
pub fn from_source<S>(source: S) -> UnscoredPipeline<E, Q, I>
where
S: Source<Q, I, E> + Send + 'static,
{
UnscoredPipeline {
stage: crate::source::source_stage(source),
}
}
pub fn from_stage(stage: Stage<E, Q, Vec<I>>) -> UnscoredPipeline<E, Q, I> {
UnscoredPipeline { stage }
}
}
impl<E: Send + 'static, Q: Send + 'static, I: Send + 'static> Pipeline<E, Q, I> {
pub fn execute(self, query: Q) -> Io<E, Vec<ScoredCandidate<I>>> {
self.stage.apply(query)
}
}