pipecircuit 0.0.5

Correct. Robust. Fast. Portable.
Documentation
use crate::{Participant, StateMachine};

/// An exhaustive semantic router for one cohesive logic unit.
///
/// A switchboard is itself a participant. Its input is the addressed sum of
/// its boundary input and internal participant outputs. Its output is the
/// addressed sum of internal participant inputs and its boundary output.
pub trait Switchboard: StateMachine + Participant {
    type BoundaryIn<'message>;
    type BoundaryOut<'message>;

    #[must_use = "switchboard outputs must be routed or settled"]
    fn route<'message>(
        &mut self,
        input: <Self as Participant>::In<'message>,
    ) -> <Self as Participant>::Out<'message>;
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{NoopTurnObserver, TurnContext};

    struct Router;

    impl StateMachine for Router {}

    impl Participant for Router {
        type In<'message> = &'message str;
        type Out<'message> = usize;
    }

    impl Switchboard for Router {
        type BoundaryIn<'message> = &'message str;
        type BoundaryOut<'message> = usize;

        fn route<'message>(
            &mut self,
            input: <Self as Participant>::In<'message>,
        ) -> <Self as Participant>::Out<'message> {
            input.len()
        }
    }

    #[test]
    fn switchboard_routes_its_declared_input_to_its_declared_output() {
        assert_eq!(Router.route("route me"), 8);
    }

    #[test]
    fn turn_context_routes_the_switchboard_decision() {
        let mut turn = TurnContext::new(NoopTurnObserver);

        assert_eq!(turn.route(&mut Router, "route me"), 8);
    }
}