use crate::{connection::Connection, error::ZerustError, router::Router};
use std::sync::Arc;
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::oneshot;
pub struct Server {
addr: String,
router: Arc<dyn Router + Send + Sync>,
}
impl Server {
pub fn new(addr: &str, router: Arc<dyn Router + Send + Sync>) -> Self {
Self {
addr: addr.to_string(),
router,
}
}
pub async fn run(&self, mut shutdown: oneshot::Receiver<()>) -> Result<(), ZerustError> {
let listener = TcpListener::bind(&self.addr).await?;
loop {
tokio::select! {
accept_result = listener.accept() =>{
match accept_result {
Ok((stream, _addr)) => {
let router = self.router.clone();
tokio::spawn(async move {
let _ = Self::handle_connection(stream, router).await;
});
}
Err(e) => return Err(ZerustError::IoError(e)),
}
}
_ = &mut shutdown =>{
break Ok(()) }
}
}
}
async fn handle_connection(
stream: TcpStream,
router: Arc<dyn Router>,
) -> Result<(), ZerustError> {
let mut conn = Connection::new(stream);
loop {
let req = match conn.read_request().await {
Ok(req) => req,
Err(e) => {
return Err(e);
}
};
let resp = router.handle(&req);
conn.send_response(&resp).await?;
}
}
}