flow::query

This commit is contained in:
AF 2023-07-31 15:38:42 +00:00
parent 7f1d72898d
commit c2102268e4
2 changed files with 138 additions and 0 deletions

View File

@ -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
View 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 {}