1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ Copyright: (c) 2023, Mike 'PhiSyX' S. (https://github.com/PhiSyX) ┃
// ┃ SPDX-License-Identifier: MPL-2.0 ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ ┃
// ┃ This Source Code Form is subject to the terms of the Mozilla Public ┃
// ┃ License, v. 2.0. If a copy of the MPL was not distributed with this ┃
// ┃ file, You can obtain one at https://mozilla.org/MPL/2.0/. ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
use std::path;
use super::Error;
use crate::routing;
// --------- //
// Interface //
// --------- //
/// Interface d'application web.
pub trait Application {
/// Routeur de l'application.
type Router: routing::interface::RouterExt<State = Self::State>;
/// État utilisateur de l'application.
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;
/// Définit le mode d'exécution du programme.
fn define_process_mode(self, mode: super::env::EnvProcessMode) -> Self
where
Self: Sized;
/// Définit les arguments de la CLI, filtrés par les champs de la structure
/// implémentant l'interface [CLI_Interface].
fn with_cli_args(self) -> Self
where
Self: Sized;
/// Définit les variables d'environnement, filtrés par les champs de la
/// structure implémentant l'interface [ENV_Interface].
fn with_env_vars(self) -> Result<Self, Error>
where
Self: Sized;
}
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
{
// NOTE(phisyx): ici typiquement un maybe async aurait été vraiment
// sympa.
// Dans le cas où l'on voudrait récupérer les variables d'environnement
// depuis une URL distant.
/* #[async] */
fn setup(_: &crate::application::Settings) -> Result<Self, Error>
where
Self: Sized;
/// Récupère les variables d'environnement à partir du contenu d'un fichier
/// et retourne une structure avec les données du contenu du fichier en
/// guise de valeurs pour chaque champ.
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)
}
}
// -------------- //
// Implémentation // -> Interface
// -------------- //
impl ApplicationCLIInterface for () {
fn arguments() -> Self
where
Self: Sized,
{
}
}
impl ApplicationEnvInterface for () {
fn setup(_: &crate::application::Settings) -> Result<Self, Error>
where
Self: Sized,
{
Ok(())
}
}