use crate::future_wrapper::FutureWrapper;
use crate::resolve::{Env, Path, ResolvedPath};
use futures::future::join_all;
use std::fmt::Debug;
use std::hash::Hash;
use super::{Filterable, Injectable};
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg>: Debug + 'rslv {
type EnvContainer;
fn map_into_env<F: 'rslv + FnMut(Path<LABEL>) -> Self::EnvContainer>(
self,
f: F,
) -> Self::EnvContainer;
}
pub trait PathContainerWf<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO, DEQO>:
PathContainer<'sg, 'rslv, LABEL, DATA, EnvContainer = Self::EnvContainerWf>
where
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
type EnvContainerWf: Injectable<'sg, 'rslv, LABEL, DATA, DWFO>
+ Filterable<'sg, 'rslv, LABEL, DATA, DEQO>;
}
impl<'sg, 'rslv, LABEL, DATA, DWFO, DEQO, T> PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO, DEQO>
for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: PathContainer<'sg, 'rslv, LABEL, DATA>,
Self::EnvContainer:
Injectable<'sg, 'rslv, LABEL, DATA, DWFO> + Filterable<'sg, 'rslv, LABEL, DATA, DEQO>,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
type EnvContainerWf = Self::EnvContainer;
}
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA>
for Vec<Path<LABEL>>
where
Self: 'rslv,
LABEL: Clone + Hash + Eq,
DATA: Hash + Eq,
{
type EnvContainer = Env<'sg, LABEL, DATA>;
fn map_into_env<F: FnMut(Path<LABEL>) -> Self::EnvContainer>(self, f: F) -> Self::EnvContainer {
self.into_iter().map(f).collect()
}
}
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, E: Debug + 'rslv>
PathContainer<'sg, 'rslv, LABEL, DATA> for Result<Vec<Path<LABEL>>, E>
where
Self: 'rslv,
LABEL: Clone + Hash,
DATA: Hash,
for<'a> ResolvedPath<'a, LABEL, DATA>: Hash + Eq,
{
type EnvContainer = Result<Env<'sg, LABEL, DATA>, E>;
fn map_into_env<F: FnMut(Path<LABEL>) -> Self::EnvContainer>(self, f: F) -> Self::EnvContainer {
self.and_then(|paths| {
paths
.into_iter()
.map(f)
.collect::<Result<Env<'sg, LABEL, DATA>, E>>()
})
}
}
impl<'sg, 'rslv, LABEL: 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA>
for FutureWrapper<'rslv, Vec<Path<LABEL>>>
where
Self: 'rslv,
LABEL: Clone + Hash,
DATA: Hash,
for<'a> ResolvedPath<'a, LABEL, DATA>: Hash + Eq,
{
type EnvContainer = FutureWrapper<'rslv, Env<'sg, LABEL, DATA>>;
fn map_into_env<F: 'rslv + FnMut(Path<LABEL>) -> Self::EnvContainer>(
self,
f: F,
) -> Self::EnvContainer {
let future = async move {
let paths = self.0.await;
let env_futures = paths.into_iter().map(f).map(|i| i.0);
let envs = join_all(env_futures).await;
envs.into_iter().collect::<Env<_, _>>()
};
FutureWrapper::new(future)
}
}