use either::Either;
use super::{guard::Guard, request::Request, response::{Response, Status}};
use std::{error::Error, future::Future, pin::Pin};
use crate::types::method::Method;
use libcoerced::{generic::Text, json};
type RequestVerify = Either<Text, json::Json>;
pub struct Route {
pub method: Method,
pub function: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Result<Response, Box<dyn Error>>>>> + 'static>,
pub request_verify: RequestVerify,
pub response_verify: ResponseVerificationMap,
pub guard: Guard
}
#[allow(dead_code)]
impl Route {
pub fn new_basic(
method: Method,
function: impl Fn(Request) -> RouteResponse + 'static
) -> Self {
Route {
method,
function: Box::new(function),
request_verify: Either::Left(Text::Any()),
response_verify: Box::new([]),
guard: Guard::Any()
}
}
pub fn new(
method: Method,
function: impl Fn(Request) -> Pin<Box<dyn Future<Output = Result<Response, Box<dyn Error>>>>> + 'static,
request_verify: Option<RequestVerify>,
response_verify: Option<ResponseVerificationMap>,
guard: Guard
) -> Self {
Route {
method,
function: Box::new(function),
request_verify: request_verify.unwrap_or(Either::Left(Text::Any())),
response_verify: response_verify.unwrap_or(Box::new([])),
guard
}
}
}
impl Default for Route {
fn default() -> Self {
Route {
method: Method::Get,
function: Box::new(|_| Box::pin(async { Ok(Response::new(Status::from_u16(200))) })),
request_verify: Either::Left(Text::Any()),
response_verify: Box::new([]),
guard: Guard::Any()
}
}
}
#[allow(dead_code)]
pub type RouteResponse = Pin<Box<dyn Future<Output = Result<Response, Box<dyn Error>>>>>;
#[allow(dead_code)]
pub type ResponseVerificationMap = Box<[(Status, RequestVerify) ]>;