use tokio::sync::{broadcast, mpsc, watch};
use std::{fmt::Debug, sync::{Arc, RwLock}};
pub const ALPN: &str = "evergreen/0.1.0";
pub enum FilterResult {
Close,
}
pub type ConnectionFilter = Arc<dyn Fn(&iroh::EndpointId, &wire::InitialPayload) -> FilterResult + Send + Sync>;
fn default_filter(addr: &iroh::EndpointId, info: &wire::InitialPayload) -> FilterResult {
todo!()
}
#[derive(Clone)]
pub struct EvergreenHandler
{
room_id: watch::Sender<u64>,
broadcast: broadcast::Sender<()>,
update_sender: mpsc::Sender<()>,
blocklist: Arc<RwLock<Vec<()>>>,
filter: ConnectionFilter,
}
impl Debug for EvergreenHandler {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EvergreenHandler").field("room_id", &self.room_id).field("broadcast", &self.broadcast).field("update_sender", &self.update_sender).field("blocklist", &self.blocklist).finish()
}
}
pub struct Evergreen
{
connection_updates: mpsc::Receiver<()>,
endpoint: iroh::Endpoint,
room_id: watch::Sender<u64>,
broadcast: broadcast::Sender<()>,
blocklist: Arc<RwLock<Vec<()>>>,
}
pub fn new(endpoint: iroh::Endpoint) -> (Evergreen, EvergreenHandler) {
let room_id = watch::Sender::new(0);
let broadcast = broadcast::Sender::<()>::new(1028);
let (update_sender, connection_updates) = mpsc::channel::<()>(1028);
let blocklist = Arc::new(RwLock::new(Vec::with_capacity(128)));
let filter = Arc::new(default_filter);
let evergreen = Evergreen {
connection_updates,
endpoint,
room_id: room_id.clone(),
broadcast: broadcast.clone(),
blocklist: blocklist.clone(),
};
let handler = EvergreenHandler {
room_id,
broadcast,
update_sender,
blocklist,
filter,
};
(evergreen, handler)
}
impl Evergreen {
pub async fn join_room() {
todo!()
}
pub async fn recv(&mut self) -> Option<()> {
self.connection_updates.recv().await
}
}
#[derive(thiserror::Error, Debug)]
enum Error {
#[error(transparent)]
ConnectionError(#[from] iroh::endpoint::ConnectionError),
#[error("Packet provided was too large")]
PacketSizeError(#[from] iroh::endpoint::ReadToEndError),
#[error("Could not deserialize packet")]
ProtoBufError(#[from] protobuf::ParseError),
#[error("Packet was not of type Init")]
NotInit,
}
const OK: u32 = 0;
const ERR_MALFORMED_PACKET: u32 = 1;
const ERR_NOT_ALLOWED: u32 = 2;
use iroh::protocol::AcceptError;
use crate::wire;
impl EvergreenHandler {
async fn incoming_handshake(&self, connection: &iroh::endpoint::Connection) -> Result<(), Error> {
{
let room_id = self.room_id.borrow();
}
let (send, mut recv) = connection.accept_bi().await?;
let data = recv.read_to_end(512).await?;
let packet = wire::deserialize_packet(&data)?;
let wire::Packet::Init(payload) = packet else {return Err(Error::NotInit)};
let filter_result = (self.filter)(&connection.remote_id(), &payload);
todo!();
}
async fn outgoing_handshake(&self, connection: &iroh::endpoint::Connection) -> Result<(), Error> {
todo!()
}
async fn event_loop(&self, connection: iroh::endpoint::Connection) -> Result<(), Error> {
let room = self.room_id.subscribe();
let packets = self.broadcast.subscribe();
todo!()
}
}
impl iroh::protocol::ProtocolHandler for EvergreenHandler {
async fn accept(&self, connection: iroh::endpoint::Connection) -> Result<(), iroh::protocol::AcceptError> {
self.incoming_handshake(&connection).await.map_err(iroh::protocol::AcceptError::from_err)?;
self.event_loop(connection).await.map_err(iroh::protocol::AcceptError::from_err)
}
}