use std::path;
use super::Error;
use crate::routing;
pub trait Application {
type Router: routing::interface::RouterExt<State = Self::State>;
type State;
fn register_extension(
_: &crate::state::State<Self::State>,
router: routing::AxumRouter<Self::State>,
) -> routing::AxumRouter<Self::State> {
router
}
fn register_layer(
_: &crate::state::State<Self::State>,
router: routing::AxumRouter<Self::State>,
) -> routing::AxumRouter<Self::State> {
router
}
fn register_middleware(
_: &crate::state::State<Self::State>,
router: routing::AxumRouter<Self::State>,
) -> routing::AxumRouter<Self::State> {
router
}
fn register_service(
server: crate::server::Server<Self::State>,
) -> crate::server::Server<Self::State> {
server
}
}
#[async_trait::async_trait]
pub trait ApplicationExt {
type CLI: ApplicationCLIInterface;
type ENV: ApplicationEnvInterface;
fn define_process_mode(self, mode: super::env::EnvProcessMode) -> Self
where
Self: Sized;
fn with_cli_args(self) -> Self
where
Self: Sized;
fn with_env_vars(self) -> Result<Self, Error>
where
Self: Sized;
fn cli_args(&self) -> &Self::CLI;
fn env_vars(&self) -> &Self::ENV;
}
pub trait ApplicationCLIInterface:
std::fmt::Debug + Clone + Send + Sync
{
fn arguments() -> Self
where
Self: Sized;
fn shared(self) -> std::sync::Arc<Self>
where
Self: Sized,
{
std::sync::Arc::new(self)
}
}
pub trait ApplicationEnvInterface:
std::fmt::Debug + Clone + Send + Sync
{
fn setup(_: &crate::application::Settings) -> Result<Self, Error>
where
Self: Sized;
fn fetch_from_file<T>(
env_filepath: impl AsRef<path::Path>,
) -> Result<T, Error>
where
T: serde::de::DeserializeOwned,
{
Ok(lexa_env::from_file(env_filepath)?)
}
}
pub trait ApplicationLoggerInterface {
fn using_logger(self) -> Result<Self, Error>
where
Self: Sized,
{
eprintln!(
"WARN: You need to implement the method \
`ApplicationLoggerInterface#using_logger` for `{}`.",
std::any::type_name::<Self>()
);
Ok(self)
}
fn using_logger_with_settings(
self,
_: super::settings::LoggerSettings,
) -> Result<Self, Error>
where
Self: Sized,
{
eprintln!(
"WARN: You need to implement the method \
`ApplicationLoggerInterface#using_logger_with_settings` for `{}`.",
std::any::type_name::<Self>()
);
Ok(self)
}
}
#[async_trait::async_trait]
pub trait Service: Send + Sync {
type Payload;
async fn subscribe(_: &Self::Payload) -> Result<Self, super::ServiceError>
where
Self: Sized;
}
impl ApplicationCLIInterface for () {
fn arguments() -> Self
where
Self: Sized,
{
}
}
impl ApplicationEnvInterface for () {
fn setup(_: &crate::application::Settings) -> Result<Self, Error>
where
Self: Sized,
{
Ok(())
}
}