use std::{borrow::Cow, pin::Pin};
use topcoat_core::{context::Cx, error::Result};
use crate::{Body, Methods, OwnedMethods, Path, Response};
pub type RouteFuture<'cx> = Pin<Box<dyn Future<Output = Result<Response>> + Send + 'cx>>;
pub trait Route: Send + Sync + 'static {
fn methods(&self) -> Methods<'_>;
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 {
methods: OwnedMethods,
path: Cow<'static, Path>,
handle: RouteHandlerFn,
}
impl RouteFn {
pub fn new(
methods: impl Into<OwnedMethods>,
path: Cow<'static, Path>,
handle: RouteHandlerFn,
) -> Self {
Self::const_new(methods.into(), path, handle)
}
pub const fn const_new(
methods: OwnedMethods,
path: Cow<'static, Path>,
handle: RouteHandlerFn,
) -> Self {
Self {
methods,
path,
handle,
}
}
}
impl Route for RouteFn {
fn methods(&self) -> Methods<'_> {
self.methods.as_methods()
}
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);