use async_trait::async_trait;
use iroh::endpoint::Connection;
use iroh::EndpointId;
use super::automerge_sync::SyncDirection;
pub const CAP_AUTOMERGE_ALPN: &[u8] = b"cap/automerge/1";
#[async_trait]
pub trait SyncTransport: Send + Sync + 'static {
fn get_connection(&self, peer_id: &EndpointId) -> Option<Connection>;
async fn get_or_connect(&self, peer_id: &EndpointId) -> anyhow::Result<Connection> {
self.get_connection(peer_id)
.ok_or_else(|| anyhow::anyhow!("no connection to peer"))
}
fn connected_peers(&self) -> Vec<EndpointId>;
}
#[async_trait]
pub trait SyncRouter: Send + Sync + 'static {
async fn get_targets(
&self,
direction: SyncDirection,
connected: &[EndpointId],
) -> Vec<EndpointId>;
async fn is_leader(&self) -> bool;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_alpn_identifier_is_valid() {
assert_eq!(CAP_AUTOMERGE_ALPN, b"cap/automerge/1");
assert!(!CAP_AUTOMERGE_ALPN.is_empty());
assert!(CAP_AUTOMERGE_ALPN.len() < 256);
assert!(CAP_AUTOMERGE_ALPN.iter().all(|b| b.is_ascii()));
}
#[test]
fn test_alpn_contains_version() {
let alpn_str = std::str::from_utf8(CAP_AUTOMERGE_ALPN).unwrap();
assert!(
alpn_str.contains("/1"),
"ALPN should include version suffix"
);
assert!(
alpn_str.starts_with("cap/"),
"ALPN should start with protocol prefix"
);
}
}