use std::{io, net::SocketAddr, sync::OnceLock};
use tokio::sync::{mpsc, oneshot};
use crate::connections::Connection;
mod handshake;
mod on_connect;
mod on_disconnect;
mod reading;
mod writing;
pub use handshake::Handshake;
pub use on_connect::OnConnect;
pub use on_disconnect::OnDisconnect;
pub use reading::Reading;
pub use writing::Writing;
#[derive(Default)]
pub(crate) struct Protocols {
pub(crate) handshake: OnceLock<ProtocolHandler<Connection, io::Result<Connection>>>,
pub(crate) reading: OnceLock<ProtocolHandler<Connection, io::Result<Connection>>>,
pub(crate) writing: OnceLock<writing::WritingHandler>,
pub(crate) on_connect: OnceLock<ProtocolHandler<SocketAddr, ()>>,
pub(crate) on_disconnect: OnceLock<ProtocolHandler<SocketAddr, ()>>,
}
pub(crate) type ReturnableItem<T, U> = (T, oneshot::Sender<U>);
pub(crate) type ReturnableConnection = ReturnableItem<Connection, io::Result<Connection>>;
pub(crate) struct ProtocolHandler<T, U>(mpsc::UnboundedSender<ReturnableItem<T, U>>);
pub(crate) trait Protocol<T, U> {
fn trigger(&self, item: ReturnableItem<T, U>);
}
impl<T, U> Protocol<T, U> for ProtocolHandler<T, U> {
fn trigger(&self, item: ReturnableItem<T, U>) {
let _ = self.0.send(item);
}
}