🔥 Remove unwrap usage to improve new apps setup

This commit is contained in:
Manuel Cillero 2024-02-26 07:39:08 +01:00
parent b7cb4363bd
commit d66063a1f7
6 changed files with 79 additions and 60 deletions

View file

@ -25,5 +25,5 @@ impl PackageTrait for Drust {
#[pagetop::main] #[pagetop::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
Application::prepare(&Drust).unwrap().run()?.await Application::prepare(&Drust).run()?.await
} }

View file

@ -21,5 +21,5 @@ async fn hello_name(
#[pagetop::main] #[pagetop::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
Application::prepare(&HelloName).unwrap().run()?.await Application::prepare(&HelloName).run()?.await
} }

View file

@ -16,5 +16,5 @@ async fn hello_world(request: service::HttpRequest) -> ResultPage<Markup, ErrorP
#[pagetop::main] #[pagetop::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
Application::prepare(&HelloWorld).unwrap().run()?.await Application::prepare(&HelloWorld).run()?.await
} }

View file

@ -21,43 +21,86 @@ use std::io::Error;
pub struct Application; pub struct Application;
impl Application { impl Application {
pub fn prepare(app: PackageRef) -> Result<Self, Error> { /// Creates a new application instance without any package.
// On startup. pub fn new() -> Self {
show_banner(); Self::internal_prepare(None)
}
// Inicia registro de trazas y eventos. /// Prepares an application instance with a specific package.
pub fn prepare(app: PackageRef) -> Self {
Self::internal_prepare(Some(app))
}
// Internal method to prepare the application, optionally with a package.
fn internal_prepare(app: Option<PackageRef>) -> Self {
// On startup, show the application banner.
Self::show_banner();
// Starts logging and event tracing.
LazyStatic::force(&trace::TRACING); LazyStatic::force(&trace::TRACING);
// Valida el identificador global de idioma. // Validates the global language identifier.
LazyStatic::force(&locale::LANGID); LazyStatic::force(&locale::LANGID);
#[cfg(feature = "database")] #[cfg(feature = "database")]
// Conecta con la base de datos. // Connects to the database.
LazyStatic::force(&db::DBCONN); LazyStatic::force(&db::DBCONN);
// Registra los paquetes de la aplicación. // Registers the application's packages.
package::all::register_packages(app); if let Some(app) = app {
package::all::register_packages(app);
}
// Registra acciones de los paquetes. // Registers package actions.
package::all::register_actions(); package::all::register_actions();
// Inicializa los paquetes. // Initializes the packages.
package::all::init_packages(); package::all::init_packages();
#[cfg(feature = "database")] #[cfg(feature = "database")]
// Ejecuta actualizaciones pendientes de la base de datos. // Runs pending database migrations.
package::all::run_migrations(); package::all::run_migrations();
Ok(Self) Self
} }
// Displays the application banner based on the configuration.
fn show_banner() {
if config::SETTINGS.app.startup_banner.to_lowercase() != "off" {
// Application name, formatted for the terminal width if necessary.
let mut app_name = config::SETTINGS.app.name.to_string();
if let Some((term_width, _)) = term_size::dimensions() {
if term_width >= 80 {
let maxlen = (term_width / 10) - 2;
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_name = ff.to_string();
}
}
}
println!("\n{}", app_name);
// Application description.
if !config::SETTINGS.app.description.is_empty() {
println!("{}\n", config::SETTINGS.app.description);
};
// PageTop version.
println!("Powered by PageTop {}\n", env!("CARGO_PKG_VERSION"));
}
}
/// Starts the web server.
pub fn run(self) -> Result<service::Server, Error> { pub fn run(self) -> Result<service::Server, Error> {
// Generate cookie key. // Generate the cookie key.
let secret_key = service::cookie::Key::generate(); let secret_key = service::cookie::Key::generate();
// Prepara el servidor web. // Prepares the web server.
Ok(service::HttpServer::new(move || { Ok(service::HttpServer::new(move || {
service_app() Self::service_app()
.wrap(tracing_actix_web::TracingLogger::default()) .wrap(tracing_actix_web::TracingLogger::default())
.wrap( .wrap(
SessionMiddleware::builder(CookieSessionStore::default(), secret_key.clone()) SessionMiddleware::builder(CookieSessionStore::default(), secret_key.clone())
@ -82,6 +125,7 @@ impl Application {
.run()) .run())
} }
/// Method for testing, returns a service application instance.
pub fn test( pub fn test(
self, self,
) -> service::App< ) -> service::App<
@ -93,50 +137,25 @@ impl Application {
InitError = (), InitError = (),
>, >,
> { > {
service_app() Self::service_app()
} }
}
fn service_app() -> service::App< // Configures the service application.
impl service::Factory< fn service_app() -> service::App<
service::Request, impl service::Factory<
Config = (), service::Request,
Response = service::Response<service::BoxBody>, Config = (),
Error = service::Error, Response = service::Response<service::BoxBody>,
InitError = (), Error = service::Error,
>, InitError = (),
> { >,
service::App::new() > {
.configure(package::all::configure_services) service::App::new()
.default_service(service::web::route().to(service_not_found)) .configure(package::all::configure_services)
.default_service(service::web::route().to(service_not_found))
}
} }
async fn service_not_found(request: service::HttpRequest) -> ResultPage<Markup, ErrorPage> { async fn service_not_found(request: service::HttpRequest) -> ResultPage<Markup, ErrorPage> {
Err(ErrorPage::NotFound(request)) Err(ErrorPage::NotFound(request))
} }
fn show_banner() {
if config::SETTINGS.app.startup_banner.to_lowercase() != "off" {
// Application name.
let mut app_name = config::SETTINGS.app.name.to_string();
if let Some((term_width, _)) = term_size::dimensions() {
if term_width >= 80 {
let maxlen = (term_width / 10) - 2;
let mut app = app_name.substring(0, maxlen).to_owned();
if app_name.len() > maxlen {
app = format!("{}...", app);
}
app_name = figfont::FIGFONT.convert(&app).unwrap().to_string();
}
}
println!("\n{}", app_name);
// Application description.
if !config::SETTINGS.app.description.is_empty() {
println!("{}\n", config::SETTINGS.app.description);
};
// PageTop version.
println!("Powered by PageTop {}\n", env!("CARGO_PKG_VERSION"));
}
}

View file

@ -48,7 +48,7 @@
//! //!
//! #[pagetop::main] //! #[pagetop::main]
//! async fn main() -> std::io::Result<()> { //! async fn main() -> std::io::Result<()> {
//! Application::prepare(&HelloWorld).unwrap().run()?.await //! Application::prepare(&HelloWorld).run()?.await
//! } //! }
//! ``` //! ```
//! This program implements a package named `HelloWorld` with one service that returns a web page //! This program implements a package named `HelloWorld` with one service that returns a web page

View file

@ -6,7 +6,7 @@ impl PackageTrait for HealthCheck {}
#[pagetop::test] #[pagetop::test]
async fn health_check_works() { async fn health_check_works() {
let app = service::test::init_service(Application::prepare(&HealthCheck).unwrap().test()).await; let app = service::test::init_service(Application::prepare(&HealthCheck).test()).await;
let req = service::test::TestRequest::get().uri("/").to_request(); let req = service::test::TestRequest::get().uri("/").to_request();
let _resp = service::test::call_service(&app, req).await; let _resp = service::test::call_service(&app, req).await;