flow::query
This commit is contained in:
parent
7f1d72898d
commit
c2102268e4
@ -4,5 +4,6 @@
|
|||||||
|
|
||||||
pub mod binary;
|
pub mod binary;
|
||||||
pub mod comparator;
|
pub mod comparator;
|
||||||
|
pub mod query;
|
||||||
pub mod speculative;
|
pub mod speculative;
|
||||||
pub mod traversible;
|
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