use std::fmt::Debug;
use std::hash::Hash;
use crate::resolve::Path;
use crate::Scope;
use crate::{future_wrapper::FutureWrapper, resolve::ResolvedPath};
use super::{PathContainer, PathContainerWf};
pub trait ScopeContainer<'sg, 'rslv, LABEL: Debug + 'sg, DATA: 'sg>: Debug {
type PathContainer;
fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer;
}
pub trait ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO, DEQO>:
ScopeContainer<'sg, 'rslv, LABEL, DATA, PathContainer = Self::PathContainerWf>
where
LABEL: Debug + 'sg,
DATA: 'sg,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
type PathContainerWf: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO, DEQO>;
}
impl<'sg, 'rslv, LABEL, DATA, DWFO, DEQO, T> ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO, DEQO>
for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: ScopeContainer<'sg, 'rslv, LABEL, DATA>,
Self::PathContainer: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO, DEQO>,
ResolvedPath<'sg, LABEL, DATA>: Eq + Hash + Clone,
{
type PathContainerWf = Self::PathContainer;
}
impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg>
ScopeContainer<'sg, 'rslv, LABEL, DATA> for Vec<Scope>
where
Vec<Path<LABEL>>: PathContainer<'sg, 'rslv, LABEL, DATA>,
{
type PathContainer = Vec<Path<LABEL>>;
fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {
self.into_iter()
.filter_map(move |s| prefix.step(lbl, s))
.collect()
}
}
impl<
'sg: 'rslv,
'rslv,
LABEL: Debug + Copy + Eq + Hash + 'sg,
DATA: Eq + Hash + 'sg,
SC: ScopeContainer<'sg, 'rslv, LABEL, DATA>,
E: Debug,
> ScopeContainer<'sg, 'rslv, LABEL, DATA> for Result<SC, E>
where
Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA>,
{
type PathContainer = Result<SC::PathContainer, E>;
fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {
self.map(|sc| sc.lift_step(lbl, prefix))
}
}
impl<
'sg: 'rslv,
'rslv,
LABEL: Debug + Copy + Eq + Hash + 'sg,
DATA: Eq + Hash + 'sg,
SC: ScopeContainer<'sg, 'rslv, LABEL, DATA> + Clone,
> ScopeContainer<'sg, 'rslv, LABEL, DATA> for FutureWrapper<'rslv, SC>
where
LABEL: Copy,
Self: 'rslv,
LABEL: 'rslv,
SC::PathContainer: Clone,
{
type PathContainer = FutureWrapper<'rslv, SC::PathContainer>;
fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {
FutureWrapper::new(async move { self.0.await.lift_step(lbl, prefix.clone()) })
}
}