use std::{io::Error as IoError, net::SocketAddr, sync::Arc};
use axum::Router;
use tokio::net::TcpListener;
use crate::{handler::UpdateHandler, types::Update};
#[cfg_attr(nightly, doc(cfg(feature = "webhook")))]
pub struct WebhookServer {
router: Router,
}
impl WebhookServer {
pub fn new<A, B>(path: A, handler: B) -> Self
where
A: AsRef<str>,
B: UpdateHandler + Send + Sync + 'static,
{
let router = Router::new()
.route(path.as_ref(), axum::routing::post(handle_update::<B>))
.layer(axum::Extension(Arc::new(handler)));
Self { router }
}
pub async fn run<T>(self, address: T) -> Result<SocketAddr, IoError>
where
T: Into<SocketAddr>,
{
let listener = TcpListener::bind(address.into()).await?;
let result = listener.local_addr();
axum::serve(listener, self.router).await?;
result
}
}
impl From<WebhookServer> for Router {
fn from(value: WebhookServer) -> Self {
value.router
}
}
async fn handle_update<H>(handler: axum::Extension<Arc<H>>, axum::extract::Json(update): axum::extract::Json<Update>)
where
H: UpdateHandler,
{
handler.handle(update).await
}