Compare commits

..

No commits in common. "2c52af4b9d68bdd5be1b3befa9a4886a0fa7e8f6" and "eb18690a5c9a6ad6846f1e32c6bb8731fc7596bb" have entirely different histories.

8 changed files with 1379 additions and 310 deletions

1572
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -11,25 +11,30 @@
</div> </div>
## Sobre PageTop ## 🧭 Sobre PageTop
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web [PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
configurables, basadas en HTML, CSS y JavaScript. configurables, basadas en HTML, CSS y JavaScript.
## Descripción general
## 🗺️ Descripción general
Este *crate* permite incluir archivos estáticos en el ejecutable de las aplicaciones PageTop para Este *crate* permite incluir archivos estáticos en el ejecutable de las aplicaciones PageTop para
servirlos de forma eficiente vía web, con detección de cambios que optimizan el tiempo de servirlos de forma eficiente vía web, con detección de cambios que optimizan el tiempo de
compilación. compilación.
## Créditos
Para ello, adapta el código de [static-files](https://crates.io/crates/static_files) (versión ## 📚 Créditos
[0.2.5](https://github.com/static-files-rs/static-files/tree/v0.2.5)) desarrollado por
[Alexander Korolev](https://crates.io/users/kilork), bajo licencia MIT/Apache 2.0. La implementación Para ello, adapta el código de los *crates* [static-files](https://crates.io/crates/static_files)
se integra en PageTop para evitar que cada proyecto tenga que declarar `static-files` manualmente (versión [0.2.5](https://github.com/static-files-rs/static-files/tree/v0.2.5)) y
como dependencia en su `Cargo.toml`. [actix-web-static-files](https://crates.io/crates/actix_web_static_files) (versión
[4.0.1](https://github.com/kilork/actix-web-static-files/tree/v4.0.1)), desarrollados ambos por
[Alexander Korolev](https://crates.io/users/kilork).
Estas implementaciones se integran en PageTop para evitar que cada proyecto tenga que declarar
`static-files` manualmente como dependencia en su `Cargo.toml`.
## 🚧 Advertencia ## 🚧 Advertencia

View file

@ -26,11 +26,14 @@ compilación.
## Créditos ## Créditos
Para ello, adapta el código de [static-files](https://crates.io/crates/static_files) (versión Para ello, adapta el código de los *crates* [static-files](https://crates.io/crates/static_files)
[0.2.5](https://github.com/static-files-rs/static-files/tree/v0.2.5)) desarrollado por (versión [0.2.5](https://github.com/static-files-rs/static-files/tree/v0.2.5)) y
[Alexander Korolev](https://crates.io/users/kilork), bajo licencia MIT/Apache 2.0. La implementación [actix-web-static-files](https://crates.io/crates/actix_web_static_files) (versión
se integra en PageTop para evitar que cada proyecto tenga que declarar `static-files` manualmente [4.0.1](https://github.com/kilork/actix-web-static-files/tree/v4.0.1)), desarrollados ambos por
como dependencia en su `Cargo.toml`. [Alexander Korolev](https://crates.io/users/kilork).
Estas implementaciones se integran en PageTop para evitar que cada proyecto tenga que declarar
`static-files` manualmente como dependencia en su `Cargo.toml`.
*/ */
#![doc(test(no_crate_inject))] #![doc(test(no_crate_inject))]
@ -41,7 +44,7 @@ como dependencia en su `Cargo.toml`.
/// Resource definition and single module based generation. /// Resource definition and single module based generation.
pub mod resource; pub mod resource;
pub use resource::Resource as StaticFile; pub use resource::Resource as StaticResource;
mod resource_dir; mod resource_dir;
pub use resource_dir::{ResourceDir, resource_dir}; pub use resource_dir::{ResourceDir, resource_dir};

View file

@ -93,9 +93,9 @@ pub fn generate_resources<P: AsRef<Path>, G: AsRef<Path>>(
/// ```rust /// ```rust
/// use std::collections::HashMap; /// use std::collections::HashMap;
/// ///
/// use pagetop_statics::StaticFile; /// use pagetop_statics::StaticResource;
/// ///
/// fn generate_mapping() -> HashMap<&'static str, StaticFile> { /// fn generate_mapping() -> HashMap<&'static str, StaticResource> {
/// include!(concat!(env!("OUT_DIR"), "/generated_mapping.rs")) /// include!(concat!(env!("OUT_DIR"), "/generated_mapping.rs"))
/// } /// }
/// ///
@ -221,7 +221,7 @@ pub(crate) fn generate_function_header<F: Write>(
) -> io::Result<()> { ) -> io::Result<()> {
writeln!( writeln!(
f, f,
"#[allow(clippy::unreadable_literal)] pub fn {fn_name}() -> ::std::collections::HashMap<&'static str, ::{crate_name}::StaticFile> {{", "#[allow(clippy::unreadable_literal)] pub fn {fn_name}() -> ::std::collections::HashMap<&'static str, ::{crate_name}::StaticResource> {{",
) )
} }

View file

@ -116,7 +116,7 @@ where
writeln!( writeln!(
module_file, module_file,
" "
use ::{crate_name}::StaticFile; use ::{crate_name}::StaticResource;
use ::std::collections::HashMap;" use ::std::collections::HashMap;"
)?; )?;
@ -177,7 +177,7 @@ fn create_set_module_file(module_dir: &Path, module_index: usize) -> io::Result<
"#[allow(clippy::wildcard_imports)] "#[allow(clippy::wildcard_imports)]
use super::*; use super::*;
#[allow(clippy::unreadable_literal)] #[allow(clippy::unreadable_literal)]
pub(crate) fn generate({DEFAULT_VARIABLE_NAME}: &mut HashMap<&'static str, StaticFile>) {{", pub(crate) fn generate({DEFAULT_VARIABLE_NAME}: &mut HashMap<&'static str, StaticResource>) {{",
)?; )?;
Ok(set_module) Ok(set_module)

View file

@ -270,14 +270,46 @@ impl<T: Default> Default for PreEscaped<T> {
/// ``` /// ```
pub const DOCTYPE: PreEscaped<&'static str> = PreEscaped("<!DOCTYPE html>"); pub const DOCTYPE: PreEscaped<&'static str> = PreEscaped("<!DOCTYPE html>");
mod axum_support { mod actix_support {
use super::PreEscaped; extern crate alloc;
use axum::response::{Html, IntoResponse, Response};
/// Convierte un bloque de [`Markup`](super::Markup) en una respuesta HTTP HTML 200. use core::{
impl IntoResponse for PreEscaped<String> { pin::Pin,
fn into_response(self) -> Response { task::{Context, Poll},
Html(self.0).into_response() };
use crate::html::PreEscaped;
use actix_web::{
body::{BodySize, MessageBody},
http::header,
web::Bytes,
HttpRequest, HttpResponse, Responder,
};
use alloc::string::String;
impl MessageBody for PreEscaped<String> {
type Error = <String as MessageBody>::Error;
fn size(&self) -> BodySize {
self.0.size()
}
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Self::Error>>> {
Pin::new(&mut self.0).poll_next(cx)
}
}
impl Responder for PreEscaped<String> {
type Body = String;
fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
HttpResponse::Ok()
.content_type(header::ContentType::html())
.message_body(self.0)
.unwrap()
} }
} }
} }
@ -286,7 +318,7 @@ mod axum_support {
pub mod html_private { pub mod html_private {
extern crate alloc; extern crate alloc;
use super::{Render, display}; use super::{display, Render};
use alloc::string::String; use alloc::string::String;
use core::fmt::Display; use core::fmt::Display;

View file

@ -134,26 +134,26 @@ pub const PAGETOP_VERSION: &str = env!("CARGO_PKG_VERSION");
pub use pagetop_macros::{AutoDefault, builder_fn, html, main, test}; pub use pagetop_macros::{AutoDefault, builder_fn, html, main, test};
pub use pagetop_statics::{StaticFile, resource}; pub use pagetop_statics::{StaticResource, resource};
pub use getter_methods::Getters; pub use getter_methods::Getters;
/// Contenedor para un conjunto de recursos embebidos. /// Contenedor para un conjunto de recursos embebidos.
#[derive(AutoDefault)] #[derive(AutoDefault)]
pub struct StaticResources { pub struct StaticResources {
bundle: HashMap<&'static str, StaticFile>, bundle: HashMap<&'static str, StaticResource>,
} }
impl StaticResources { impl StaticResources {
/// Crea un contenedor para un conjunto de recursos generado por `build.rs` (consultar /// Crea un contenedor para un conjunto de recursos generado por `build.rs` (consultar
/// [`pagetop_build`](https://docs.rs/pagetop-build)). /// [`pagetop_build`](https://docs.rs/pagetop-build)).
pub fn new(bundle: HashMap<&'static str, StaticFile>) -> Self { pub fn new(bundle: HashMap<&'static str, StaticResource>) -> Self {
Self { bundle } Self { bundle }
} }
} }
impl Deref for StaticResources { impl Deref for StaticResources {
type Target = HashMap<&'static str, StaticFile>; type Target = HashMap<&'static str, StaticResource>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.bundle &self.bundle

View file

@ -5,8 +5,6 @@
//! el módulo `http` para tipos de bajo nivel como `StatusCode`, `HeaderName` o `Method`. También //! el módulo `http` para tipos de bajo nivel como `StatusCode`, `HeaderName` o `Method`. También
//! ofrece utilidades para servir archivos estáticos, [`ServeDir`] y [`ServeEmbedded`]. //! ofrece utilidades para servir archivos estáticos, [`ServeDir`] y [`ServeEmbedded`].
use crate::StaticFile;
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::Infallible; use std::convert::Infallible;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
@ -27,6 +25,10 @@ pub use axum::response::{IntoResponse, Response};
// Operaciones HTTP para registrar rutas. // Operaciones HTTP para registrar rutas.
pub use axum::routing::{delete, get, patch, post, put}; pub use axum::routing::{delete, get, patch, post, put};
// Servicios para archivos estáticos (disco y embebidos).
pub use pagetop_statics::StaticResource;
pub use tower_http::services::ServeDir;
// **< HttpRequest >******************************************************************************** // **< HttpRequest >********************************************************************************
/// Representa una petición HTTP. /// Representa una petición HTTP.
@ -89,11 +91,6 @@ impl<S: Send + Sync> FromRequestParts<S> for HttpRequest {
} }
} }
// **< ServeDir >***********************************************************************************
// Servicio para archivos estáticos en disco.
pub use tower_http::services::ServeDir;
// **< ServeEmbedded >****************************************************************************** // **< ServeEmbedded >******************************************************************************
/// Servicio para archivos estáticos embebidos en el binario. /// Servicio para archivos estáticos embebidos en el binario.
@ -107,12 +104,12 @@ pub use tower_http::services::ServeDir;
/// recursos con un [`Arc`](std::sync::Arc) para evitar copias innecesarias. /// recursos con un [`Arc`](std::sync::Arc) para evitar copias innecesarias.
#[derive(Clone)] #[derive(Clone)]
pub struct ServeEmbedded { pub struct ServeEmbedded {
files: std::sync::Arc<HashMap<&'static str, StaticFile>>, files: std::sync::Arc<HashMap<&'static str, StaticResource>>,
} }
impl ServeEmbedded { impl ServeEmbedded {
/// Crea un nuevo servicio a partir del mapa de recursos embebidos generado por `build.rs`. /// Crea un nuevo servicio a partir del mapa de recursos embebidos generado por `build.rs`.
pub fn new(files: HashMap<&'static str, StaticFile>) -> Self { pub fn new(files: HashMap<&'static str, StaticResource>) -> Self {
Self { Self {
files: std::sync::Arc::new(files), files: std::sync::Arc::new(files),
} }