hibana 0.9.6

Choreography-derived runtime enforcement kernel for no_std Rust multiparty protocols
Documentation
use super::{
    ClusterError, DecisionArm, DynamicResolverKey, ErasedResolverRef, RendezvousId, ResolverRef,
    ResolverRegistrationKey, SessionCluster,
};
use crate::global::const_dsl::DynamicRouteResolver;
impl<'cfg, T> SessionCluster<'cfg, T>
where
    T: crate::transport::Transport + 'cfg,
{
    fn ensure_dynamic_resolver_capacity(
        &self,
        rv_id: RendezvousId,
        additional_entries: usize,
    ) -> Result<(), ClusterError> {
        if additional_entries == 0 {
            return Ok(());
        }
        self.locals()
            .ensure_dynamic_resolver_capacity(rv_id, additional_entries)
    }

    pub(crate) fn dynamic_resolver(
        &self,
        key: DynamicResolverKey,
    ) -> Option<ErasedResolverRef<'cfg>> {
        self.locals().dynamic_resolver(key)
    }

    pub(crate) fn set_resolver<const RESOLVER: u16, const ROLE: u8>(
        &self,
        rv_id: RendezvousId,
        program: &crate::runtime::program::RoleProgram<ROLE>,
        resolver: ResolverRef<'cfg, RESOLVER>,
    ) -> Result<(), ClusterError> {
        self.with_resident_program_ref(rv_id, program, |compiled| {
            if compiled.route_resolver_sites_for(RESOLVER).next().is_none() {
                return Err(ClusterError::ResolverReject {
                    resolver_id: RESOLVER,
                });
            }
            let key =
                DynamicResolverKey::new(rv_id, ResolverRegistrationKey::new(compiled, RESOLVER));
            if self.dynamic_resolver(key).is_none() {
                self.ensure_dynamic_resolver_capacity(rv_id, 1)?;
            }
            self.commit_prepared_dynamic_resolver(key, resolver);
            Ok(())
        })
    }

    fn commit_prepared_dynamic_resolver<const RESOLVER: u16>(
        &self,
        key: DynamicResolverKey,
        resolver_ref: ResolverRef<'cfg, RESOLVER>,
    ) {
        if key.registration().resolver_id() != RESOLVER {
            crate::invariant();
        }
        crate::invariant_ok(
            self.locals()
                .insert_dynamic_resolver(key, resolver_ref.erase()),
        );
    }

    pub(crate) fn resolve_dynamic_resolver(
        &self,
        rv_id: RendezvousId,
        program: &'static crate::global::compiled::images::CompiledProgramRef,
        resolver: DynamicRouteResolver,
    ) -> Result<DecisionArm, ClusterError> {
        let resolver_id = resolver.resolver_id();
        let key =
            DynamicResolverKey::new(rv_id, ResolverRegistrationKey::new(program, resolver_id));
        let Some(resolver_ref) = self.dynamic_resolver(key) else {
            return Err(ClusterError::DynamicResolverInvariant { resolver_id });
        };

        let arm = resolver_ref
            .resolve_decision()
            .map_err(|_| ClusterError::ResolverReject { resolver_id })?;
        Ok(arm)
    }
}