use async_trait::async_trait;
use std::any::TypeId;
pub use dependency_injector::{Injectable, Provider};
#[async_trait]
pub trait Controller: Send + Sync + 'static {
fn base_path(&self) -> &'static str;
fn routes(&self) -> Vec<RouteDefinition>;
}
pub trait Module: Send + Sync + 'static {
fn providers(&self) -> Vec<ProviderRegistration>;
fn controllers(&self) -> Vec<ControllerRegistration>;
fn guards(&self) -> Vec<crate::module::GuardRegistration> {
vec![]
}
fn imports(&self) -> Vec<Box<dyn Module>>;
fn exports(&self) -> Vec<TypeId>;
fn re_exports(&self) -> Vec<Box<dyn Module>> {
vec![]
}
}
#[async_trait]
pub trait RequestHandler: Send + Sync {
async fn handle(
&self,
request: crate::HttpRequest,
) -> Result<crate::HttpResponse, crate::Error>;
}
pub trait Validator: Send + Sync {
fn validate(&self, value: &str) -> Result<(), String>;
}
#[derive(Clone, Debug)]
pub struct RouteDefinition {
pub method: HttpMethod,
pub path: String,
pub handler_name: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum HttpMethod {
GET,
POST,
PUT,
DELETE,
PATCH,
HEAD,
OPTIONS,
}
impl HttpMethod {
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Option<Self> {
match s.to_uppercase().as_str() {
"GET" => Some(HttpMethod::GET),
"POST" => Some(HttpMethod::POST),
"PUT" => Some(HttpMethod::PUT),
"DELETE" => Some(HttpMethod::DELETE),
"PATCH" => Some(HttpMethod::PATCH),
"HEAD" => Some(HttpMethod::HEAD),
"OPTIONS" => Some(HttpMethod::OPTIONS),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
HttpMethod::GET => "GET",
HttpMethod::POST => "POST",
HttpMethod::PUT => "PUT",
HttpMethod::DELETE => "DELETE",
HttpMethod::PATCH => "PATCH",
HttpMethod::HEAD => "HEAD",
HttpMethod::OPTIONS => "OPTIONS",
}
}
}
#[derive(Clone)]
pub struct ProviderRegistration {
pub type_id: TypeId,
pub type_name: &'static str,
pub register_fn: fn(&crate::container::Container),
}
impl std::fmt::Debug for ProviderRegistration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ProviderRegistration")
.field("type_id", &self.type_id)
.field("type_name", &self.type_name)
.finish()
}
}
#[derive(Clone)]
pub struct ControllerRegistration {
pub type_id: TypeId,
pub type_name: &'static str,
pub base_path: &'static str,
pub factory:
fn(&crate::Container) -> Result<Box<dyn std::any::Any + Send + Sync>, crate::Error>,
#[allow(clippy::type_complexity)]
pub route_registrar: fn(
&crate::Container,
&mut crate::Router,
Box<dyn std::any::Any + Send + Sync>,
) -> Result<(), crate::Error>,
}
impl std::fmt::Debug for ControllerRegistration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ControllerRegistration")
.field("type_id", &self.type_id)
.field("type_name", &self.type_name)
.field("base_path", &self.base_path)
.finish()
}
}