use crate::completeness::FutureCompleteness;
use crate::{
completeness::private::Sealed,
completeness::{
Completeness, CriticalEdgeBasedCompleteness, CriticalEdgeSet, Delay, EdgeClosedError,
EdgesOrDelay,
},
label::Label,
InnerScopeGraph, Scope, ScopeGraph,
};
use std::{collections::HashSet, hash::Hash};
#[derive(Debug)]
pub struct ExplicitClose<LABEL> {
critical_edges: CriticalEdgeSet<LABEL>,
}
impl<LABEL> Default for ExplicitClose<LABEL> {
fn default() -> Self {
ExplicitClose {
critical_edges: CriticalEdgeSet::default(),
}
}
}
impl<LABEL> Sealed for ExplicitClose<LABEL> {}
impl<LABEL: Hash + Eq + Label, DATA> Completeness<LABEL, DATA> for ExplicitClose<LABEL> {
fn cmpl_new_scope(&self, _: &InnerScopeGraph<LABEL, DATA>, _: Scope) {
<ExplicitClose<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
self,
LABEL::iter().collect(), )
}
fn cmpl_new_complete_scope(&self, _: &InnerScopeGraph<LABEL, DATA>, _: Scope) {
<ExplicitClose<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
self,
HashSet::new(), )
}
type NewEdgeResult = Result<(), EdgeClosedError<LABEL>>;
fn cmpl_new_edge(
&self,
inner_scope_graph: &InnerScopeGraph<LABEL, DATA>,
src: Scope,
lbl: LABEL,
dst: Scope,
) -> Self::NewEdgeResult {
if self.critical_edges.is_open(src, &lbl) {
inner_scope_graph.add_edge(src, lbl, dst);
Ok(())
} else {
Err(EdgeClosedError {
scope: src,
label: lbl,
})
}
}
type GetEdgesResult<'rslv> = EdgesOrDelay<Vec<Scope>, LABEL>
where
Self: 'rslv, LABEL: 'rslv, DATA: 'rslv;
fn cmpl_get_edges<'rslv>(
&self,
inner_scope_graph: &InnerScopeGraph<LABEL, DATA>,
src: Scope,
lbl: LABEL,
) -> Self::GetEdgesResult<'rslv>
where
LABEL: 'rslv,
DATA: 'rslv,
{
if self.critical_edges.is_open(src, &lbl) {
Err(Delay {
scope: src,
label: lbl,
})
} else {
Ok(inner_scope_graph.get_edges(src, lbl))
}
}
}
impl<LABEL: Hash + Eq + Label, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
for ExplicitClose<LABEL>
{
fn init_scope_with(&self, open_labels: HashSet<LABEL>) {
self.critical_edges.init_scope(open_labels)
}
}
impl<LABEL: Hash + Eq> ExplicitClose<LABEL> {
pub(super) fn close(&self, scope: Scope, label: &LABEL) {
self.critical_edges.close(scope, label);
}
}
impl<'sg, LABEL: Hash + Eq, DATA> ScopeGraph<'sg, LABEL, DATA, ExplicitClose<LABEL>> {
pub fn close(&self, scope: Scope, label: &LABEL) {
self.completeness.close(scope, label)
}
}
impl<'sg, LABEL: Hash + Eq + Copy, DATA> ScopeGraph<'sg, LABEL, DATA, FutureCompleteness<LABEL>> {
pub fn close(&self, scope: Scope, label: &LABEL) {
self.completeness.close(scope, label)
}
}