1use std::{any::Any, collections::BTreeMap, sync::Arc};
2
3use anyhow::Result;
4use futures_buffered::join_all;
5use futures_lite::future::Boxed as BoxedFuture;
6use iroh_net::endpoint::Connecting;
7
8pub trait ProtocolHandler: Send + Sync + IntoArcAny + std::fmt::Debug + 'static {
18 fn accept(self: Arc<Self>, conn: Connecting) -> BoxedFuture<Result<()>>;
22
23 fn shutdown(self: Arc<Self>) -> BoxedFuture<()> {
25 Box::pin(async move {})
26 }
27}
28
29pub trait IntoArcAny {
33 fn into_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
34}
35
36impl<T: Send + Sync + 'static> IntoArcAny for T {
37 fn into_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
38 self
39 }
40}
41
42#[derive(Debug, Clone, Default)]
44pub struct ProtocolMap(BTreeMap<Vec<u8>, Arc<dyn ProtocolHandler>>);
45
46impl ProtocolMap {
47 pub fn get_typed<P: ProtocolHandler>(&self, alpn: &[u8]) -> Option<Arc<P>> {
49 let protocol: Arc<dyn ProtocolHandler> = self.0.get(alpn)?.clone();
50 let protocol_any: Arc<dyn Any + Send + Sync> = protocol.into_arc_any();
51 let protocol_ref = Arc::downcast(protocol_any).ok()?;
52 Some(protocol_ref)
53 }
54
55 pub fn get(&self, alpn: &[u8]) -> Option<Arc<dyn ProtocolHandler>> {
57 self.0.get(alpn).cloned()
58 }
59
60 pub fn insert(&mut self, alpn: Vec<u8>, handler: Arc<dyn ProtocolHandler>) {
62 self.0.insert(alpn, handler);
63 }
64
65 pub fn alpns(&self) -> impl Iterator<Item = &Vec<u8>> {
67 self.0.keys()
68 }
69
70 pub async fn shutdown(&self) {
74 let handlers = self.0.values().cloned().map(ProtocolHandler::shutdown);
75 join_all(handlers).await;
76 }
77}