✨ Añade lectura de configuración global y modular
- Soporta jerarquía de ficheros TOML que mapean ajustes a estructuras fuertemente tipadas con valores predefinidos. - Permite definir configuraciones distintas para cada entorno. - Añade la macro `include_config!` para facilitar la asignación modular de ajustes de configuración. - Añade documentación detallada y tests de verificación.
This commit is contained in:
parent
cbee4c2cb8
commit
f7dbd90af2
14 changed files with 4938 additions and 4 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,2 +1,7 @@
|
|||
# Ignora directorios de compilación
|
||||
**/target
|
||||
|
||||
# Archivos de configuración locales
|
||||
**/local.*.toml
|
||||
**/local.toml
|
||||
.env
|
||||
|
|
141
Cargo.lock
generated
141
Cargo.lock
generated
|
@ -319,6 +319,27 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.15.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "595aae20e65c3be792d05818e8c63025294ac3cb7e200f11459063a352a6ef80"
|
||||
dependencies = [
|
||||
"pathdiff",
|
||||
"serde",
|
||||
"toml",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.16.2"
|
||||
|
@ -424,6 +445,22 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "figlet-rs"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4742a071cd9694fc86f9fa1a08fa3e53d40cc899d7ee532295da2d085639fbc5"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.2"
|
||||
|
@ -712,6 +749,12 @@ version = "0.2.174"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "litemap"
|
||||
version = "0.8.0"
|
||||
|
@ -807,10 +850,16 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|||
|
||||
[[package]]
|
||||
name = "pagetop"
|
||||
version = "0.0.1"
|
||||
version = "0.0.2"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"colored",
|
||||
"config",
|
||||
"figlet-rs",
|
||||
"pagetop-macros",
|
||||
"serde",
|
||||
"substring",
|
||||
"terminal_size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -843,6 +892,12 @@ dependencies = [
|
|||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -994,6 +1049,19 @@ version = "0.1.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
|
@ -1038,6 +1106,15 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
|
@ -1104,6 +1181,15 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "substring"
|
||||
version = "1.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.104"
|
||||
|
@ -1126,6 +1212,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.41"
|
||||
|
@ -1197,6 +1293,40 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.41"
|
||||
|
@ -1367,6 +1497,15 @@ version = "0.52.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pagetop"
|
||||
version = "0.0.1"
|
||||
version = "0.0.2"
|
||||
edition = "2021"
|
||||
|
||||
description = """\
|
||||
|
@ -15,6 +15,13 @@ license.workspace = true
|
|||
authors.workspace = true
|
||||
|
||||
[dependencies]
|
||||
colored = "3.0.0"
|
||||
config = { version = "0.15.11", default-features = false, features = ["toml"] }
|
||||
figlet-rs = "0.1.5"
|
||||
serde.workspace = true
|
||||
substring = "1.4.5"
|
||||
terminal_size = "0.4.2"
|
||||
|
||||
actix-web = "4.11.0"
|
||||
|
||||
pagetop-macros.workspace = true
|
||||
|
@ -34,5 +41,7 @@ license = "MIT OR Apache-2.0"
|
|||
authors = ["Manuel Cillero <manuel@cillero.es>"]
|
||||
|
||||
[workspace.dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
# Helpers
|
||||
pagetop-macros = { version = "0.0", path = "helpers/pagetop-macros" }
|
||||
|
|
55
src/app.rs
55
src/app.rs
|
@ -1,6 +1,10 @@
|
|||
//! Prepara y ejecuta una aplicación creada con `Pagetop`.
|
||||
|
||||
use crate::service;
|
||||
mod figfont;
|
||||
|
||||
use crate::{global, service};
|
||||
|
||||
use substring::Substring;
|
||||
|
||||
use std::io::Error;
|
||||
|
||||
|
@ -9,14 +13,61 @@ pub struct Application;
|
|||
impl Application {
|
||||
/// Crea una instancia de la aplicación.
|
||||
pub fn new() -> Self {
|
||||
// Al arrancar muestra una cabecera para la aplicación.
|
||||
Self::show_banner();
|
||||
Self
|
||||
}
|
||||
|
||||
// Muestra una cabecera para la aplicación basada en la configuración.
|
||||
fn show_banner() {
|
||||
use colored::Colorize;
|
||||
use terminal_size::{terminal_size, Width};
|
||||
|
||||
if global::SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||
// Nombre de la aplicación, ajustado al ancho del terminal si es necesario.
|
||||
let mut app_ff = String::new();
|
||||
let app_name = &global::SETTINGS.app.name;
|
||||
if let Some((Width(term_width), _)) = terminal_size() {
|
||||
if term_width >= 80 {
|
||||
let maxlen: usize = ((term_width / 10) - 2).into();
|
||||
let mut app = app_name.substring(0, maxlen).to_owned();
|
||||
if app_name.len() > maxlen {
|
||||
app = format!("{app}...");
|
||||
}
|
||||
if let Some(ff) = figfont::FIGFONT.convert(&app) {
|
||||
app_ff = ff.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
if app_ff.is_empty() {
|
||||
println!("\n{app_name}");
|
||||
} else {
|
||||
print!("\n{app_ff}");
|
||||
}
|
||||
|
||||
// Descripción de la aplicación.
|
||||
if !global::SETTINGS.app.description.is_empty() {
|
||||
println!("{}", global::SETTINGS.app.description.cyan());
|
||||
};
|
||||
|
||||
// Versión de PageTop.
|
||||
println!(
|
||||
"{} {}\n",
|
||||
"Powered by PageTop".yellow(),
|
||||
env!("CARGO_PKG_VERSION").yellow()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ejecuta el servidor web de la aplicación.
|
||||
pub fn run(self) -> Result<service::Server, Error> {
|
||||
// Prepara el servidor web.
|
||||
Ok(service::HttpServer::new(move || Self::service_app())
|
||||
.bind("localhost:8080")?
|
||||
.bind(format!(
|
||||
"{}:{}",
|
||||
&global::SETTINGS.server.bind_address,
|
||||
&global::SETTINGS.server.bind_port
|
||||
))?
|
||||
.run())
|
||||
}
|
||||
|
||||
|
|
30
src/app/figfont.rs
Normal file
30
src/app/figfont.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use crate::global;
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use figlet_rs::FIGfont;
|
||||
|
||||
pub static FIGFONT: LazyLock<FIGfont> = LazyLock::new(|| {
|
||||
let slant = include_str!("slant.flf");
|
||||
let small = include_str!("small.flf");
|
||||
let speed = include_str!("speed.flf");
|
||||
let starwars = include_str!("starwars.flf");
|
||||
|
||||
FIGfont::from_content(
|
||||
match global::SETTINGS.app.startup_banner.to_lowercase().as_str() {
|
||||
"off" => slant,
|
||||
"slant" => slant,
|
||||
"small" => small,
|
||||
"speed" => speed,
|
||||
"starwars" => starwars,
|
||||
_ => {
|
||||
println!(
|
||||
"\n FIGfont \"{}\" not found for banner. Using \"Slant\". Check settings.",
|
||||
global::SETTINGS.app.startup_banner,
|
||||
);
|
||||
slant
|
||||
}
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
});
|
1295
src/app/slant.flf
Normal file
1295
src/app/slant.flf
Normal file
File diff suppressed because it is too large
Load diff
1097
src/app/small.flf
Normal file
1097
src/app/small.flf
Normal file
File diff suppressed because it is too large
Load diff
1301
src/app/speed.flf
Normal file
1301
src/app/speed.flf
Normal file
File diff suppressed because it is too large
Load diff
719
src/app/starwars.flf
Normal file
719
src/app/starwars.flf
Normal file
|
@ -0,0 +1,719 @@
|
|||
flf2a$ 7 6 22 15 4
|
||||
starwars.flf by Ryan Youck (youck@cs.uregina.ca) Dec 25/1994
|
||||
I am not responsible for use of this font
|
||||
Based on Big.flf by Glenn Chappell
|
||||
|
||||
$ $@
|
||||
$ $@
|
||||
$ $@
|
||||
$ $@
|
||||
$ $@
|
||||
$ $@
|
||||
$ $@@
|
||||
__ $@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
|__|$@
|
||||
(__)$@
|
||||
$@@
|
||||
_ _ @
|
||||
( | )@
|
||||
V V @
|
||||
$ @
|
||||
$ @
|
||||
$ @
|
||||
@@
|
||||
_ _ @
|
||||
_| || |_$@
|
||||
|_ __ _|@
|
||||
_| || |_ @
|
||||
|_ __ _|@
|
||||
|_||_| $@
|
||||
@@
|
||||
__,--,_.@
|
||||
/ |@
|
||||
| (----`@
|
||||
\ \ $@
|
||||
.----) | $@
|
||||
|_ __/ $@
|
||||
'--' $@@
|
||||
_ ___$ @
|
||||
/ \ / /$ @
|
||||
( o ) / / $ @
|
||||
\_/ / / _$ @
|
||||
/ / / \ @
|
||||
/ / ( o )@
|
||||
/__/ \_/ @@
|
||||
@
|
||||
___ @
|
||||
( _ ) $@
|
||||
/ _ \/\@
|
||||
| (_> <@
|
||||
\___/\/@
|
||||
$@@
|
||||
__ @
|
||||
(_ )@
|
||||
|/ @
|
||||
$ @
|
||||
$ @
|
||||
$ @
|
||||
@@
|
||||
___@
|
||||
/ /@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
\__\@@
|
||||
___ @
|
||||
\ \ @
|
||||
| |@
|
||||
| |@
|
||||
| |@
|
||||
| |@
|
||||
/__/ @@
|
||||
_ @
|
||||
/\| |/\ @
|
||||
\ ` ' /$@
|
||||
|_ _|@
|
||||
/ , . \$@
|
||||
\/|_|\/ @
|
||||
@@
|
||||
@
|
||||
_ @
|
||||
_| |_$@
|
||||
|_ _|@
|
||||
|_| $@
|
||||
$ @
|
||||
@@
|
||||
@
|
||||
@
|
||||
$ @
|
||||
$ @
|
||||
__ @
|
||||
(_ )@
|
||||
|/ @@
|
||||
@
|
||||
@
|
||||
______ @
|
||||
|______|@
|
||||
$ @
|
||||
$ @
|
||||
@@
|
||||
@
|
||||
@
|
||||
@
|
||||
$ @
|
||||
__ @
|
||||
(__)@
|
||||
@@
|
||||
___@
|
||||
/ /@
|
||||
/ / @
|
||||
/ /$ @
|
||||
/ /$ @
|
||||
/__/$ @
|
||||
@@
|
||||
___ $@
|
||||
/ _ \ $@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| |_| |$@
|
||||
\___/ $@
|
||||
$@@
|
||||
__ $@
|
||||
/_ |$@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
|_|$@
|
||||
$@@
|
||||
___ $@
|
||||
|__ \ $@
|
||||
$) |$@
|
||||
/ / $@
|
||||
/ /_ $@
|
||||
|____|$@
|
||||
$@@
|
||||
____ $@
|
||||
|___ \ $@
|
||||
__) |$@
|
||||
|__ < $@
|
||||
___) |$@
|
||||
|____/ $@
|
||||
$@@
|
||||
_ _ $@
|
||||
| || | $@
|
||||
| || |_ $@
|
||||
|__ _|$@
|
||||
| | $@
|
||||
|_| $@
|
||||
$@@
|
||||
_____ $@
|
||||
| ____|$@
|
||||
| |__ $@
|
||||
|___ \ $@
|
||||
___) |$@
|
||||
|____/ $@
|
||||
$@@
|
||||
__ $@
|
||||
/ / $@
|
||||
/ /_ $@
|
||||
| '_ \ $@
|
||||
| (_) |$@
|
||||
\___/ $@
|
||||
$@@
|
||||
______ $@
|
||||
|____ |$@
|
||||
$/ / $@
|
||||
/ / $@
|
||||
/ / $@
|
||||
/_/ $@
|
||||
$@@
|
||||
___ $@
|
||||
/ _ \ $@
|
||||
| (_) |$@
|
||||
> _ < $@
|
||||
| (_) |$@
|
||||
\___/ $@
|
||||
$@@
|
||||
___ $@
|
||||
/ _ \ $@
|
||||
| (_) |$@
|
||||
\__, |$@
|
||||
/ / $@
|
||||
/_/ $@
|
||||
$@@
|
||||
@
|
||||
_ @
|
||||
(_)@
|
||||
$ @
|
||||
_ @
|
||||
(_)@
|
||||
@@
|
||||
@
|
||||
_ @
|
||||
(_)@
|
||||
$ @
|
||||
_ @
|
||||
( )@
|
||||
|/ @@
|
||||
___@
|
||||
/ /@
|
||||
/ /$@
|
||||
< <$ @
|
||||
\ \$@
|
||||
\__\@
|
||||
@@
|
||||
@
|
||||
______ @
|
||||
|______|@
|
||||
______ @
|
||||
|______|@
|
||||
@
|
||||
@@
|
||||
___ @
|
||||
\ \$ @
|
||||
\ \ @
|
||||
> >@
|
||||
/ / @
|
||||
/__/$ @
|
||||
@@
|
||||
______ $@
|
||||
| \ $@
|
||||
`----) |$@
|
||||
/ / $@
|
||||
|__| $@
|
||||
__ $@
|
||||
(__) $@@
|
||||
____ @
|
||||
/ __ \ @
|
||||
/ / _` |@
|
||||
| | (_| |@
|
||||
\ \__,_|@
|
||||
\____/ @
|
||||
@@
|
||||
___ $ @
|
||||
/ \ $ @
|
||||
/ ^ \$ @
|
||||
/ /_\ \$ @
|
||||
/ _____ \$ @
|
||||
/__/ \__\$@
|
||||
$@@
|
||||
.______ $@
|
||||
| _ \ $@
|
||||
| |_) |$@
|
||||
| _ < $@
|
||||
| |_) |$@
|
||||
|______/ $@
|
||||
$@@
|
||||
______$@
|
||||
/ |@
|
||||
| ,----'@
|
||||
| | $@
|
||||
| `----.@
|
||||
\______|@
|
||||
$@@
|
||||
_______ $@
|
||||
| \$@
|
||||
| .--. |@
|
||||
| | | |@
|
||||
| '--' |@
|
||||
|_______/$@
|
||||
$@@
|
||||
_______ @
|
||||
| ____|@
|
||||
| |__ $@
|
||||
| __| $@
|
||||
| |____ @
|
||||
|_______|@
|
||||
@@
|
||||
_______ @
|
||||
| ____|@
|
||||
| |__ $@
|
||||
| __| $@
|
||||
| | $ @
|
||||
|__| @
|
||||
@@
|
||||
_______ @
|
||||
/ _____|@
|
||||
| | __ $@
|
||||
| | |_ |$@
|
||||
| |__| |$@
|
||||
\______|$@
|
||||
$@@
|
||||
__ __ $@
|
||||
| | | |$@
|
||||
| |__| |$@
|
||||
| __ |$@
|
||||
| | | |$@
|
||||
|__| |__|$@
|
||||
$@@
|
||||
__ $@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
|__|$@
|
||||
$@@
|
||||
__ $@
|
||||
| |$@
|
||||
| |$@
|
||||
.--. | |$@
|
||||
| `--' |$@
|
||||
\______/ $@
|
||||
$@@
|
||||
__ ___$@
|
||||
| |/ /$@
|
||||
| ' / $@
|
||||
| < $@
|
||||
| . \ $@
|
||||
|__|\__\$@
|
||||
$@@
|
||||
__ $@
|
||||
| | $@
|
||||
| | $@
|
||||
| | $@
|
||||
| `----.@
|
||||
|_______|@
|
||||
$@@
|
||||
.___ ___.$@
|
||||
| \/ |$@
|
||||
| \ / |$@
|
||||
| |\/| |$@
|
||||
| | | |$@
|
||||
|__| |__|$@
|
||||
$@@
|
||||
.__ __.$@
|
||||
| \ | |$@
|
||||
| \| |$@
|
||||
| . ` |$@
|
||||
| |\ |$@
|
||||
|__| \__|$@
|
||||
$@@
|
||||
______ $@
|
||||
/ __ \ $@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| `--' |$@
|
||||
\______/ $@
|
||||
$@@
|
||||
.______ $@
|
||||
| _ \ $@
|
||||
| |_) |$@
|
||||
| ___/ $@
|
||||
| | $ @
|
||||
| _| $ @
|
||||
$ @@
|
||||
______ $ @
|
||||
/ __ \ $ @
|
||||
| | | | $ @
|
||||
| | | | $ @
|
||||
| `--' '--. @
|
||||
\_____\_____\@
|
||||
$ @@
|
||||
.______ $ @
|
||||
| _ \ $ @
|
||||
| |_) | $ @
|
||||
| / $ @
|
||||
| |\ \----.@
|
||||
| _| `._____|@
|
||||
$@@
|
||||
_______.@
|
||||
/ |@
|
||||
| (----`@
|
||||
\ \ $@
|
||||
.----) | $@
|
||||
|_______/ $@
|
||||
$@@
|
||||
.___________.@
|
||||
| |@
|
||||
`---| |----`@
|
||||
| | $ @
|
||||
| | $ @
|
||||
|__| $ @
|
||||
$ @@
|
||||
__ __ $@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| `--' |$@
|
||||
\______/ $@
|
||||
$@@
|
||||
____ ____$@
|
||||
\ \ / /$@
|
||||
\ \/ /$ @
|
||||
\ /$ @
|
||||
\ /$ @
|
||||
\__/$ @
|
||||
$ @@
|
||||
____ __ ____$@
|
||||
\ \ / \ / /$@
|
||||
\ \/ \/ /$ @
|
||||
\ /$ @
|
||||
\ /\ /$ @
|
||||
\__/ \__/$ @
|
||||
$ @@
|
||||
___ ___$@
|
||||
\ \ / /$@
|
||||
\ V / $@
|
||||
> < $@
|
||||
/ . \ $@
|
||||
/__/ \__\$@
|
||||
$@@
|
||||
____ ____$@
|
||||
\ \ / /$@
|
||||
\ \/ /$ @
|
||||
\_ _/$ @
|
||||
| |$ @
|
||||
|__|$ @
|
||||
$ @@
|
||||
________ $@
|
||||
| / $@
|
||||
`---/ / $@
|
||||
/ / $@
|
||||
/ /----.@
|
||||
/________|@
|
||||
$@@
|
||||
____ @
|
||||
| |@
|
||||
| |-`@
|
||||
| | $@
|
||||
| | $@
|
||||
| |-.@
|
||||
|____|@@
|
||||
___ @
|
||||
\ \ $ @
|
||||
\ \$ @
|
||||
\ \$ @
|
||||
\ \$@
|
||||
\__\@
|
||||
@@
|
||||
____ @
|
||||
| |@
|
||||
`-| |@
|
||||
| |@
|
||||
| |@
|
||||
.-| |@
|
||||
|____|@@
|
||||
___ @
|
||||
/ \ @
|
||||
/--^--\@
|
||||
$@
|
||||
$@
|
||||
$@
|
||||
$@@
|
||||
@
|
||||
@
|
||||
@
|
||||
$ @
|
||||
$ @
|
||||
______ @
|
||||
|______|@@
|
||||
__ @
|
||||
( _)@
|
||||
\| @
|
||||
$ @
|
||||
$ @
|
||||
$ @
|
||||
@@
|
||||
___ $ @
|
||||
/ \ $ @
|
||||
/ ^ \$ @
|
||||
/ /_\ \$ @
|
||||
/ _____ \$ @
|
||||
/__/ \__\$@
|
||||
$@@
|
||||
.______ $@
|
||||
| _ \ $@
|
||||
| |_) |$@
|
||||
| _ < $@
|
||||
| |_) |$@
|
||||
|______/ $@
|
||||
$@@
|
||||
______$@
|
||||
/ |@
|
||||
| ,----'@
|
||||
| | $@
|
||||
| `----.@
|
||||
\______|@
|
||||
$@@
|
||||
_______ $@
|
||||
| \$@
|
||||
| .--. |@
|
||||
| | | |@
|
||||
| '--' |@
|
||||
|_______/$@
|
||||
$@@
|
||||
_______ @
|
||||
| ____|@
|
||||
| |__ $@
|
||||
| __| $@
|
||||
| |____ @
|
||||
|_______|@
|
||||
@@
|
||||
_______ @
|
||||
| ____|@
|
||||
| |__ $@
|
||||
| __| $@
|
||||
| | $ @
|
||||
|__| @
|
||||
@@
|
||||
_______ @
|
||||
/ _____|@
|
||||
| | __ $@
|
||||
| | |_ |$@
|
||||
| |__| |$@
|
||||
\______|$@
|
||||
$@@
|
||||
__ __ $@
|
||||
| | | |$@
|
||||
| |__| |$@
|
||||
| __ |$@
|
||||
| | | |$@
|
||||
|__| |__|$@
|
||||
$@@
|
||||
__ $@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
|__|$@
|
||||
$@@
|
||||
__ $@
|
||||
| |$@
|
||||
| |$@
|
||||
.--. | |$@
|
||||
| `--' |$@
|
||||
\______/ $@
|
||||
$@@
|
||||
__ ___$@
|
||||
| |/ /$@
|
||||
| ' / $@
|
||||
| < $@
|
||||
| . \ $@
|
||||
|__|\__\$@
|
||||
$@@
|
||||
__ $@
|
||||
| | $@
|
||||
| | $@
|
||||
| | $@
|
||||
| `----.@
|
||||
|_______|@
|
||||
$@@
|
||||
.___ ___.$@
|
||||
| \/ |$@
|
||||
| \ / |$@
|
||||
| |\/| |$@
|
||||
| | | |$@
|
||||
|__| |__|$@
|
||||
$@@
|
||||
.__ __.$@
|
||||
| \ | |$@
|
||||
| \| |$@
|
||||
| . ` |$@
|
||||
| |\ |$@
|
||||
|__| \__|$@
|
||||
$@@
|
||||
______ $@
|
||||
/ __ \ $@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| `--' |$@
|
||||
\______/ $@
|
||||
$@@
|
||||
.______ $@
|
||||
| _ \ $@
|
||||
| |_) |$@
|
||||
| ___/ $@
|
||||
| | $ @
|
||||
| _| $ @
|
||||
$ @@
|
||||
______ $ @
|
||||
/ __ \ $ @
|
||||
| | | | $ @
|
||||
| | | | $ @
|
||||
| `--' '--. @
|
||||
\_____\_____\@
|
||||
$ @@
|
||||
.______ $ @
|
||||
| _ \ $ @
|
||||
| |_) | $ @
|
||||
| / $ @
|
||||
| |\ \----.@
|
||||
| _| `._____|@
|
||||
$@@
|
||||
_______.@
|
||||
/ |@
|
||||
| (----`@
|
||||
\ \ $@
|
||||
.----) | $@
|
||||
|_______/ $@
|
||||
$@@
|
||||
.___________.@
|
||||
| |@
|
||||
`---| |----`@
|
||||
| | $ @
|
||||
| | $ @
|
||||
|__| $ @
|
||||
$ @@
|
||||
__ __ $@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| | | |$@
|
||||
| `--' |$@
|
||||
\______/ $@
|
||||
$@@
|
||||
____ ____$@
|
||||
\ \ / /$@
|
||||
\ \/ /$ @
|
||||
\ /$ @
|
||||
\ /$ @
|
||||
\__/$ @
|
||||
$ @@
|
||||
____ __ ____$@
|
||||
\ \ / \ / /$@
|
||||
\ \/ \/ /$ @
|
||||
\ /$ @
|
||||
\ /\ /$ @
|
||||
\__/ \__/$ @
|
||||
$ @@
|
||||
___ ___$@
|
||||
\ \ / /$@
|
||||
\ V / $@
|
||||
> < $@
|
||||
/ . \ $@
|
||||
/__/ \__\$@
|
||||
$@@
|
||||
____ ____$@
|
||||
\ \ / /$@
|
||||
\ \/ /$ @
|
||||
\_ _/$ @
|
||||
| |$ @
|
||||
|__|$ @
|
||||
$ @@
|
||||
________ $@
|
||||
| / $@
|
||||
`---/ / $@
|
||||
/ / $@
|
||||
/ /----.@
|
||||
/________|@
|
||||
$@@
|
||||
___@
|
||||
/ /@
|
||||
| |$@
|
||||
/ /$ @
|
||||
\ \$ @
|
||||
| |$@
|
||||
\__\@@
|
||||
__ $@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
| |$@
|
||||
|__|$@@
|
||||
___ @
|
||||
\ \$ @
|
||||
| | @
|
||||
\ \@
|
||||
/ /@
|
||||
| | @
|
||||
/__/$ @@
|
||||
__ _ @
|
||||
/ \/ |@
|
||||
|_/\__/ @
|
||||
$ @
|
||||
$ @
|
||||
$ @
|
||||
@@
|
||||
_ _ @
|
||||
(_)_(_) @
|
||||
/ \ @
|
||||
/ _ \ @
|
||||
/ ___ \ @
|
||||
/_/ \_\@
|
||||
@@
|
||||
_ _ @
|
||||
(_)_(_)@
|
||||
/ _ \ @
|
||||
| | | |@
|
||||
| |_| |@
|
||||
\___/ @
|
||||
@@
|
||||
_ _ @
|
||||
(_) (_)@
|
||||
| | | |@
|
||||
| | | |@
|
||||
| |_| |@
|
||||
\___/ @
|
||||
@@
|
||||
_ _ @
|
||||
(_) (_)@
|
||||
__ _ @
|
||||
/ _` |@
|
||||
| (_| |@
|
||||
\__,_|@
|
||||
@@
|
||||
_ _ @
|
||||
(_) (_)@
|
||||
___ @
|
||||
/ _ \ @
|
||||
| (_) |@
|
||||
\___/ @
|
||||
@@
|
||||
_ _ @
|
||||
(_) (_)@
|
||||
_ _ @
|
||||
| | | |@
|
||||
| |_| |@
|
||||
\__,_|@
|
||||
@@
|
||||
___ @
|
||||
/ _ \ @
|
||||
| | ) |@
|
||||
| |< < @
|
||||
| | ) |@
|
||||
| ||_/ @
|
||||
|_| @@
|
179
src/config.rs
Normal file
179
src/config.rs
Normal file
|
@ -0,0 +1,179 @@
|
|||
//! Carga las opciones de configuración.
|
||||
//!
|
||||
//! Estos ajustes se obtienen de archivos [TOML](https://toml.io) como pares `clave = valor` que se
|
||||
//! mapean a estructuras **fuertemente tipadas** y valores predefinidos.
|
||||
//!
|
||||
//! Siguiendo la metodología [Twelve-Factor App](https://12factor.net/config), `PageTop` separa el
|
||||
//! **código** de la **configuración**, lo que permite tener configuraciones diferentes para cada
|
||||
//! despliegue, como *dev*, *staging* o *production*, sin modificar el código fuente.
|
||||
//!
|
||||
//!
|
||||
//! # Orden de carga
|
||||
//!
|
||||
//! Si tu aplicación necesita archivos de configuración, crea un directorio `config` en la raíz del
|
||||
//! proyecto, al mismo nivel que el archivo *Cargo.toml* o que el binario de la aplicación.
|
||||
//!
|
||||
//! `PageTop` carga en este orden, y siempre de forma opcional, los siguientes archivos TOML:
|
||||
//!
|
||||
//! 1. **config/common.toml**, para ajustes comunes a todos los entornos. Este enfoque simplifica el
|
||||
//! mantenimiento al centralizar los valores de configuración comunes.
|
||||
//!
|
||||
//! 2. **config/{rm}.toml**, donde `{rm}` es el valor de la variable de entorno `PAGETOP_RUN_MODE`:
|
||||
//!
|
||||
//! * Si `PAGETOP_RUN_MODE` no está definida, se asume el valor `default`, y `PageTop` intentará
|
||||
//! cargar *config/default.toml* si el archivo existe.
|
||||
//!
|
||||
//! * Útil para definir configuraciones específicas por entorno, garantizando que cada uno (p.e.
|
||||
//! *dev*, *staging* o *production*) disponga de sus propias opciones, como claves de API,
|
||||
//! URLs o ajustes de rendimiento, sin afectar a los demás.
|
||||
//!
|
||||
//! 3. **config/local.{rm}.toml**, útil para configuraciones locales específicas de la máquina o de
|
||||
//! la ejecución:
|
||||
//!
|
||||
//! * Permite añadir o sobrescribir ajustes propios del entorno. Por ejemplo, `local.dev.toml`
|
||||
//! para desarrollo o `local.production.toml` para retoques en producción.
|
||||
//!
|
||||
//! * Facilita que cada desarrollador adapte la configuración a su equipo en un entorno dado. Por
|
||||
//! lo general no se comparte ni se sube al sistema de control de versiones.
|
||||
//!
|
||||
//! 4. **config/local.toml**, para ajustes locales válidos en cualquier entorno, ideal para cambios
|
||||
//! rápidos o valores temporales que no dependan de un entorno concreto.
|
||||
//!
|
||||
//! Los archivos se combinan en el orden anterior, cada archivo sobrescribe a los anteriores en caso
|
||||
//! de conflicto.
|
||||
//!
|
||||
//!
|
||||
//! # Cómo añadir opciones de configuración a tu código
|
||||
//!
|
||||
//! Añade [*serde*](https://docs.rs/serde) en tu archivo *Cargo.toml* con la *feature* `derive`:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! serde = { version = "1.0", features = ["derive"] }
|
||||
//! ```
|
||||
//!
|
||||
//! Y usa la macro [`include_config!`](crate::include_config) para inicializar tus ajustes en una
|
||||
//! estructura con tipos seguros. Por ejemplo:
|
||||
//!
|
||||
//! ```rust#ignore
|
||||
//! use pagetop::prelude::*;
|
||||
//! use serde::Deserialize;
|
||||
//!
|
||||
//! include_config!(SETTINGS: Settings => [
|
||||
//! // [myapp]
|
||||
//! "myapp.name" => "Value Name",
|
||||
//! "myapp.width" => 900,
|
||||
//! "myapp.height" => 320,
|
||||
//! ]);
|
||||
//!
|
||||
//! #[derive(Debug, Deserialize)]
|
||||
//! pub struct Settings {
|
||||
//! pub myapp: MyApp,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Deserialize)]
|
||||
//! pub struct MyApp {
|
||||
//! pub name: String,
|
||||
//! pub description: Option<String>,
|
||||
//! pub width: u16,
|
||||
//! pub height: u16,
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! De esta forma estás añadiendo una nueva sección `[myapp]` a la configuración, igual que existen
|
||||
//! `[app]` o `[server]` en las opciones globales de [`Settings`](crate::global::Settings).
|
||||
//!
|
||||
//! Se recomienda proporcionar siempre valores por defecto o usar `Option<T>` para los ajustes
|
||||
//! opcionales.
|
||||
//!
|
||||
//! Si la configuración no se inicializa correctamente, la aplicación lanzará *panic* y detendrá la
|
||||
//! ejecución.
|
||||
//!
|
||||
//! Las estructuras de configuración son de **sólo lectura** durante la ejecución.
|
||||
//!
|
||||
//!
|
||||
//! # Usando tus opciones de configuración
|
||||
//!
|
||||
//! ```rust#ignore
|
||||
//! use pagetop::prelude::*;
|
||||
//! use crate::config;
|
||||
//!
|
||||
//! fn global_settings() {
|
||||
//! println!("Nombre de la app: {}", &global::SETTINGS.app.name);
|
||||
//! println!("Descripción: {}", &global::SETTINGS.app.description);
|
||||
//! println!("Run mode: {}", &global::SETTINGS.app.run_mode);
|
||||
//! }
|
||||
//!
|
||||
//! fn extension_settings() {
|
||||
//! println!("{} - {:?}", &config::SETTINGS.myapp.name, &config::SETTINGS.myapp.description);
|
||||
//! println!("{}", &config::SETTINGS.myapp.width);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use config::builder::DefaultState;
|
||||
use config::{Config, ConfigBuilder, File};
|
||||
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
|
||||
// Nombre del directorio de configuración por defecto.
|
||||
const DEFAULT_CONFIG_DIR: &str = "config";
|
||||
|
||||
// Modo de ejecución por defecto.
|
||||
const DEFAULT_RUN_MODE: &str = "default";
|
||||
|
||||
/// Valores originales cargados desde los archivos de configuración como pares `clave = valor`.
|
||||
pub static CONFIG_VALUES: LazyLock<ConfigBuilder<DefaultState>> = LazyLock::new(|| {
|
||||
// Determina el directorio de configuración:
|
||||
// - Usa CONFIG_DIR si está definido en el entorno (p.e.: CONFIG_DIR=/etc/myapp ./myapp).
|
||||
// - Si no, intenta DEFAULT_CONFIG_DIR dentro del proyecto (en CARGO_MANIFEST_DIR).
|
||||
// - Si nada de esto aplica, entonces usa DEFAULT_CONFIG_DIR relativo al ejecutable.
|
||||
let config_dir: PathBuf = if let Ok(env_dir) = env::var("CONFIG_DIR") {
|
||||
env_dir.into()
|
||||
} else if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
|
||||
let manifest_config = Path::new(&manifest_dir).join(DEFAULT_CONFIG_DIR);
|
||||
if manifest_config.exists() {
|
||||
manifest_config
|
||||
} else {
|
||||
DEFAULT_CONFIG_DIR.into()
|
||||
}
|
||||
} else {
|
||||
DEFAULT_CONFIG_DIR.into()
|
||||
};
|
||||
|
||||
// Determina el modo de ejecución según la variable de entorno PAGETOP_RUN_MODE. Por defecto usa
|
||||
// DEFAULT_RUN_MODE si no está definida (p.e.: PAGETOP_RUN_MODE=production ./myapp).
|
||||
let rm = env::var("PAGETOP_RUN_MODE").unwrap_or_else(|_| DEFAULT_RUN_MODE.into());
|
||||
|
||||
Config::builder()
|
||||
// 1. Configuración común para todos los entornos (common.toml).
|
||||
.add_source(File::from(config_dir.join("common.toml")).required(false))
|
||||
// 2. Configuración específica del entorno (p.e.: default.toml, production.toml).
|
||||
.add_source(File::from(config_dir.join(format!("{rm}.toml"))).required(false))
|
||||
// 3. Configuración local reservada para cada entorno (p.e.: local.default.toml).
|
||||
.add_source(File::from(config_dir.join(format!("local.{rm}.toml"))).required(false))
|
||||
// 4. Configuración local común (local.toml).
|
||||
.add_source(File::from(config_dir.join("local.toml")).required(false))
|
||||
// Guarda el modo de ejecución explícitamente.
|
||||
.set_override("app.run_mode", rm)
|
||||
.expect("Failed to set application run mode")
|
||||
});
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! include_config {
|
||||
( $SETTINGS:ident : $Settings:ty => [ $( $key:expr => $value:expr ),* $(,)? ] ) => {
|
||||
/// Valores asignados o predefinidos para la configuración de [`$Settings`].
|
||||
pub static $SETTINGS: std::sync::LazyLock<$Settings> = std::sync::LazyLock::new(|| {
|
||||
let mut settings = $crate::config::CONFIG_VALUES.clone();
|
||||
$(
|
||||
settings = settings.set_default($key, $value).unwrap();
|
||||
)*
|
||||
settings
|
||||
.build()
|
||||
.expect(concat!("Failed to build config for ", stringify!($Settings)))
|
||||
.try_deserialize::<$Settings>()
|
||||
.expect(concat!("Error parsing settings for ", stringify!($Settings)))
|
||||
});
|
||||
};
|
||||
}
|
57
src/global.rs
Normal file
57
src/global.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
//! Opciones de configuración globales.
|
||||
|
||||
use crate::include_config;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
include_config!(SETTINGS: Settings => [
|
||||
// [app]
|
||||
"app.name" => "Sample",
|
||||
"app.description" => "Developed with the amazing PageTop framework.",
|
||||
"app.startup_banner" => "Slant",
|
||||
|
||||
// [server]
|
||||
"server.bind_address" => "localhost",
|
||||
"server.bind_port" => 8080,
|
||||
]);
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
/// Ajustes de configuración para las secciones globales [`[app]`](App) y [`[server]`](Server).
|
||||
/// Consulta [`SETTINGS`] para los valores por defecto.
|
||||
pub struct Settings {
|
||||
pub app: App,
|
||||
pub server: Server,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
/// Sección `[app]` de la configuración.
|
||||
///
|
||||
/// Forma parte de [`Settings`].
|
||||
pub struct App {
|
||||
/// Nombre de la aplicación.
|
||||
/// Valor por defecto: *"Sample"*.
|
||||
pub name: String,
|
||||
/// Breve descripción de la aplicación.
|
||||
/// Valor por defecto: *"Developed with the amazing PageTop framework."*.
|
||||
pub description: String,
|
||||
/// ASCII banner printed at startup: *"Off"*, *"Slant"*, *"Small"*, *"Speed"*, or *"Starwars"*.
|
||||
/// Default: *"Slant"*.
|
||||
pub startup_banner: String,
|
||||
/// Modo de ejecución.
|
||||
/// Valor por defecto: el definido por la variable de entorno
|
||||
/// `PAGETOP_RUN_MODE`, o *"default"* si no está establecida.
|
||||
pub run_mode: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
/// Sección `[server]` de la configuración.
|
||||
///
|
||||
/// Forma parte de [`Settings`].
|
||||
pub struct Server {
|
||||
/// Dirección de enlace para el servidor web.
|
||||
/// Valor por defecto: *"localhost"*.
|
||||
pub bind_address: String,
|
||||
/// Puerto de escucha del servidor web.
|
||||
/// Valor por defecto: *8088*.
|
||||
pub bind_port: u16,
|
||||
}
|
|
@ -36,6 +36,10 @@ pub use pagetop_macros::{main, test};
|
|||
|
||||
// API *********************************************************************************************
|
||||
|
||||
// Carga las opciones de configuración.
|
||||
pub mod config;
|
||||
// Opciones de configuración globales.
|
||||
pub mod global;
|
||||
// Gestión del servidor y servicios web.
|
||||
pub mod service;
|
||||
// Prepara y ejecuta la aplicación.
|
||||
|
|
|
@ -4,8 +4,15 @@
|
|||
|
||||
pub use crate::{main, test};
|
||||
|
||||
// MACROS.
|
||||
|
||||
// crate::config
|
||||
pub use crate::include_config;
|
||||
|
||||
// API.
|
||||
|
||||
pub use crate::global;
|
||||
|
||||
pub use crate::service;
|
||||
|
||||
pub use crate::app::Application;
|
||||
|
|
41
tests/config.rs
Normal file
41
tests/config.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use std::env;
|
||||
|
||||
include_config!(SETTINGS: Settings => [
|
||||
"test.string_value" => "Test String",
|
||||
"test.int_value" => -321,
|
||||
"test.float_value" => 2.3456,
|
||||
]);
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Settings {
|
||||
pub test: Test,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Test {
|
||||
pub string_value: String,
|
||||
pub int_value: i32,
|
||||
pub float_value: f32,
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn check_global_config() {
|
||||
env::set_var("PAGETOP_RUN_MODE", "test");
|
||||
|
||||
assert_eq!(global::SETTINGS.app.run_mode, "test");
|
||||
assert_eq!(global::SETTINGS.app.name, "Testing");
|
||||
assert_eq!(global::SETTINGS.server.bind_port, 9000);
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn check_local_config() {
|
||||
env::set_var("PAGETOP_RUN_MODE", "test");
|
||||
|
||||
assert_eq!(SETTINGS.test.string_value, "Modified value");
|
||||
assert_eq!(SETTINGS.test.int_value, -321);
|
||||
assert_eq!(SETTINGS.test.float_value, 8.7654);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue