flow::query
This commit is contained in:
parent
7f1d72898d
commit
c2102268e4
@ -4,5 +4,6 @@
|
||||
|
||||
pub mod binary;
|
||||
pub mod comparator;
|
||||
pub mod query;
|
||||
pub mod speculative;
|
||||
pub mod traversible;
|
||||
|
137
src/flow/query.rs
Normal file
137
src/flow/query.rs
Normal file
@ -0,0 +1,137 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait Query: Copy {
|
||||
type Output;
|
||||
}
|
||||
|
||||
pub trait QueryConvert<E>: Query {
|
||||
fn convert(e: E) -> Self::Output;
|
||||
}
|
||||
|
||||
pub trait QueryEnrich<A>: Query {
|
||||
fn enrich(&self, output: Self::Output, a: A) -> Self::Output;
|
||||
}
|
||||
|
||||
pub trait QueryChain: Query {
|
||||
type Original: Query<Output = Self::Output>;
|
||||
|
||||
fn original(&self) -> &Self::Original;
|
||||
}
|
||||
|
||||
pub struct StartQuery<Q, M>(Q, PhantomData<M>);
|
||||
|
||||
impl<Q: Clone, M> Clone for StartQuery<Q, M> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone(), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Copy, M> Copy for StartQuery<Q, M> {}
|
||||
|
||||
impl<Q: Query, M> Query for StartQuery<Q, M> {
|
||||
type Output = Q::Output;
|
||||
}
|
||||
|
||||
impl<Q: Query, M> QueryChain for StartQuery<Q, M> {
|
||||
type Original = Q;
|
||||
|
||||
fn original(&self) -> &Self::Original {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
struct BootQuery;
|
||||
struct IgnoreQuery;
|
||||
|
||||
impl<Q: Query, A> QueryEnrich<A> for StartQuery<Q, BootQuery>
|
||||
where
|
||||
Q: QueryEnrich<A>,
|
||||
{
|
||||
fn enrich(&self, output: Self::Output, a: A) -> Self::Output {
|
||||
self.0.enrich(output, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Query, A> QueryEnrich<A> for StartQuery<Q, IgnoreQuery> {
|
||||
fn enrich(&self, output: Self::Output, _a: A) -> Self::Output {
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Query, E, M> QueryConvert<E> for StartQuery<Q, M>
|
||||
where
|
||||
Q: QueryConvert<E>,
|
||||
{
|
||||
fn convert(e: E) -> Self::Output {
|
||||
Q::convert(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChainQuery<Q, A>(Q, PhantomData<A>);
|
||||
|
||||
impl<Q: Clone, A> Clone for ChainQuery<Q, A> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone(), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Copy, A> Copy for ChainQuery<Q, A> {}
|
||||
|
||||
impl<Q: Query, A> Query for ChainQuery<Q, A> {
|
||||
type Output = Q::Output;
|
||||
}
|
||||
|
||||
impl<Q: QueryChain, A> QueryChain for ChainQuery<Q, A> {
|
||||
type Original = Q::Original;
|
||||
|
||||
fn original(&self) -> &Self::Original {
|
||||
self.0.original()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: QueryChain, A, Ax: Enriches<A>> QueryEnrich<Ax> for ChainQuery<Q, A>
|
||||
where
|
||||
Q: QueryEnrich<Ax>,
|
||||
Q::Original: QueryEnrich<A>,
|
||||
{
|
||||
fn enrich(&self, output: Self::Output, a: Ax) -> Self::Output {
|
||||
self.0.enrich(a.enrich(output, self.original()), a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: QueryChain, A, E> QueryConvert<E> for ChainQuery<Q, A>
|
||||
where
|
||||
Q::Original: QueryConvert<E>,
|
||||
{
|
||||
fn convert(e: E) -> Self::Output {
|
||||
<Q::Original as QueryConvert<E>>::convert(e)
|
||||
}
|
||||
}
|
||||
|
||||
trait QueryExt: Query {
|
||||
fn start<M>(self) -> StartQuery<Self, M> {
|
||||
StartQuery(self, PhantomData)
|
||||
}
|
||||
|
||||
fn enriching<A>(self) -> ChainQuery<Self, A>
|
||||
where
|
||||
Self: QueryChain,
|
||||
Self::Original: QueryEnrich<A>,
|
||||
{
|
||||
ChainQuery(self, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Query> QueryExt for Q {}
|
||||
|
||||
pub trait Enriches<A> {
|
||||
fn enrich<Output>(
|
||||
&self,
|
||||
output: Output,
|
||||
query: &impl QueryEnrich<A, Output = Output>,
|
||||
) -> Output;
|
||||
}
|
||||
|
||||
pub trait QueryJoin: QueryEnrich<<Self as Query>::Output> {}
|
||||
|
||||
impl<Q: QueryEnrich<<Q as Query>::Output>> QueryJoin for Q {}
|
Loading…
Reference in New Issue
Block a user