risq 0.4.1

Re-implementation of Bisq (https://github.com/bisq-network/bisq) in rust
use super::connection::ConnectionId;
use crate::{bisq::payload::*, prelude::*};
use actix::dev::ToEnvelope;
use std::marker::PhantomData;

pub enum Dispatch {
    Consumed,
    Retained(network_envelope::Message),
}

pub trait Dispatcher {
    fn dispatch(&self, conn: ConnectionId, msg: network_envelope::Message) -> Dispatch;
}
pub trait SendableDispatcher: Dispatcher + Clone + Send + 'static {}
impl<T: Dispatcher + Clone + Send + 'static> SendableDispatcher for T {}

pub struct Receive<M>(pub ConnectionId, pub M);
impl<M> Message for Receive<M> {
    type Result = ();
}
pub struct ActorDispatcher<A, M>
where
    M: PayloadExtractor,
    A: Actor + Handler<Receive<<M as PayloadExtractor>::Extraction>>,
{
    addr: Addr<A>,
    phantom: PhantomData<M>,
}
impl<A, M> ActorDispatcher<A, M>
where
    M: PayloadExtractor,
    A: Actor + Handler<Receive<<M as PayloadExtractor>::Extraction>>,
{
    pub fn new(addr: Addr<A>) -> Self {
        ActorDispatcher {
            addr,
            phantom: PhantomData,
        }
    }
}
impl<A, M> Dispatcher for ActorDispatcher<A, M>
where
    M: PayloadExtractor + 'static,
    A: Actor + Handler<Receive<<M as PayloadExtractor>::Extraction>>,
    <A as Actor>::Context: ToEnvelope<A, Receive<<M as PayloadExtractor>::Extraction>>,
{
    fn dispatch(&self, conn: ConnectionId, msg: network_envelope::Message) -> Dispatch {
        match <M as PayloadExtractor>::extract(msg) {
            Extract::Succeeded(extraction) => {
                arbiter_spawn!(self.addr.send(Receive(conn, extraction)));
                Dispatch::Consumed
            }
            Extract::Failed(msg) => Dispatch::Retained(msg),
        }
    }
}
impl<A, M> Clone for ActorDispatcher<A, M>
where
    M: PayloadExtractor,
    A: Actor + Handler<Receive<<M as PayloadExtractor>::Extraction>>,
{
    fn clone(&self) -> Self {
        Self {
            addr: self.addr.clone(),
            phantom: PhantomData,
        }
    }
}

pub struct Chain<F: Dispatcher + Sized> {
    first: F,
}
pub fn chain<F: Dispatcher + Sized>(first: F) -> Chain<F> {
    Chain { first }
}
impl<F: Dispatcher + Sized> Chain<F> {
    pub fn forward_to<N: Dispatcher + Sized>(self, next: N) -> ForwardTo<F, N> {
        ForwardTo {
            first: self.first,
            next,
        }
    }
}
#[derive(Clone)]
pub struct ForwardTo<F: Dispatcher + Sized, N: Dispatcher + Sized> {
    first: F,
    next: N,
}
impl<F: Dispatcher + Sized, N: Dispatcher + Sized> ForwardTo<F, N> {
    pub fn forward_to<O: Dispatcher + Sized>(self, next: O) -> ForwardTo<Self, O> {
        ForwardTo { first: self, next }
    }
}
impl<F: Dispatcher + Sized, N: Dispatcher + Sized> Dispatcher for ForwardTo<F, N> {
    fn dispatch(&self, conn: ConnectionId, msg: network_envelope::Message) -> Dispatch {
        match self.first.dispatch(conn, msg) {
            Dispatch::Consumed => Dispatch::Consumed,
            Dispatch::Retained(msg) => self.next.dispatch(conn, msg),
        }
    }
}