use std::{borrow::Cow, pin::Pin};
use http::Method;
use topcoat_core::{context::Cx, error::Result};
use crate::{Body, Path, Response};
pub type RouteFuture<'cx> = Pin<Box<dyn Future<Output = Result<Response>> + Send + 'cx>>;
pub trait Route: Send + Sync + 'static {
fn method(&self) -> Method;
fn path(&self) -> &Path;
fn handle<'cx>(&'cx self, cx: &'cx Cx, body: Body) -> RouteFuture<'cx>;
}
pub type RouteHandlerFn = for<'cx> fn(cx: &'cx Cx, body: Body) -> RouteFuture<'cx>;
#[derive(Debug, Clone)]
pub struct RouteFn {
method: Method,
path: Cow<'static, Path>,
handle: RouteHandlerFn,
}
impl RouteFn {
pub const fn new(method: Method, path: Cow<'static, Path>, handle: RouteHandlerFn) -> Self {
Self {
method,
path,
handle,
}
}
}
impl Route for RouteFn {
fn method(&self) -> Method {
self.method.clone()
}
fn path(&self) -> &Path {
&self.path
}
fn handle<'cx>(&'cx self, cx: &'cx Cx, body: Body) -> RouteFuture<'cx> {
(self.handle)(cx, body)
}
}
#[cfg(feature = "discover")]
inventory::collect!(RouteFn);