use fnv::FnvHashMap;
use libp2prs_core::multistream::Negotiator;
use libp2prs_core::muxing::IReadWrite;
use libp2prs_core::transport::TransportError;
use crate::protocol_handler::IProtocolHandler;
use crate::ProtocolId;
pub(crate) struct Muxer {
pub(crate) protocol_handlers: FnvHashMap<ProtocolId, IProtocolHandler>,
}
impl Clone for Muxer {
fn clone(&self) -> Self {
Muxer {
protocol_handlers: self.protocol_handlers.clone(),
}
}
}
impl Default for Muxer {
fn default() -> Self {
Muxer::new()
}
}
impl Muxer {
pub fn new() -> Self {
Self {
protocol_handlers: Default::default(),
}
}
}
impl Muxer {
pub(crate) fn add_protocol_handler(&mut self, p: IProtocolHandler) {
log::debug!("adding protocol handler: {:?}", p.protocol_info());
p.protocol_info().iter().for_each(|pid| {
self.protocol_handlers.insert(pid.clone(), p.clone());
});
}
pub(crate) fn supported_protocols(&self) -> impl IntoIterator<Item = ProtocolId> + '_ {
self.protocol_handlers.keys().cloned()
}
pub(crate) async fn select_inbound(
&mut self,
socket: IReadWrite,
) -> Result<(IProtocolHandler, IReadWrite, ProtocolId), TransportError> {
let protocols = self.supported_protocols();
let negotiator = Negotiator::new_with_protocols(protocols);
let (proto, socket) = negotiator.negotiate(socket).await?;
let handler = self.protocol_handlers.get_mut(&proto).unwrap().clone();
log::debug!("muxer select inbound {:?}", proto);
Ok((handler as IProtocolHandler, socket, proto))
}
}