diff --git a/.cargo/cliff.toml b/.cargo/cliff.toml deleted file mode 100644 index cbbb57b6..00000000 --- a/.cargo/cliff.toml +++ /dev/null @@ -1,69 +0,0 @@ -# cliff.toml - -[changelog] -header = """ -# CHANGELOG - -Este archivo documenta los cambios más relevantes realizados en cada versión. El formato está basado -en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/), y las versiones se numeran siguiendo -las reglas del [Versionado Semántico](https://semver.org/lang/es/). - -Resume la evolución del proyecto para usuarios y colaboradores, destacando nuevas funcionalidades, -correcciones, mejoras durante el desarrollo o cambios en la documentación. Cambios menores o -internos pueden omitirse si no afectan al uso del proyecto. -""" -trim = true -render_always = true - -body = """ -{% if version %} -## {{ version | trim_start_matches(pat="v") }} ({{ timestamp | date(format="%Y-%m-%d") }}) -{% else %} -## Pendiente de publicación -{% endif %}\ -{% for group, commits in commits | group_by(attribute="group") %} -### {{ group | upper_first }} - -{% for commit in commits %} -{%- set msg = commit.message - | split(pat="\n") - | first - | replace(from="✨ ", to="") - | replace(from="🐛 ", to="") - | replace(from="🚑 ", to="") - | replace(from="⬆️ ", to="") - | replace(from="🚧 ", to="") - | replace(from="♻️ ", to="") - | replace(from="✏️ ", to="") - | replace(from="🏷️ ", to="") - | replace(from="🧑‍💻 ", to="") - | replace(from="🍱 ", to="") - | replace(from="📝 ", to="") - | replace(from="💡 ", to="") --%} - -- {{ msg | trim }} {% if commit.author.name != "Manuel Cillero" %} - {{ commit.author.name }}{% endif %} -{% endfor %}{% endfor %} -""" - -[git] -conventional_commits = false -filter_unconventional = false -topo_order_commits = true -sort_commits = "oldest" - -commit_parsers = [ - { message = "^✨", group = "Añadido" }, - { message = "^🐛", group = "Corregido" }, - { message = "^🚑", group = "Corregido" }, - { message = "^🚧", group = "Cambiado" }, - { message = "^♻️", group = "Cambiado" }, - { message = "^✏️", group = "Cambiado" }, - { message = "^🏷️", group = "Cambiado" }, - { message = "^🧑‍💻", group = "Cambiado" }, - { message = "^🍱", group = "Cambiado" }, - { message = "^⬆️", group = "Dependencias" }, - { message = "^📝", group = "Documentado" }, - { message = "^💡", group = "Documentado" }, - { message = "^.*", group = "Otros cambios" }, -] diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index d29b0de3..00000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,3 +0,0 @@ -[alias] -ts = ["test", "--features", "testing"] # cargo ts -tw = ["test", "--workspace", "--features", "testing"] # cargo tw diff --git a/.cargo/release.toml b/.cargo/release.toml deleted file mode 100644 index 68f7a9cc..00000000 --- a/.cargo/release.toml +++ /dev/null @@ -1,25 +0,0 @@ -# release.toml - -# Etiqueta por crate: `pagetop-macros-v0.2.0` -tag-prefix = "{{crate_name}}-" - -# Confirmaciones firmadas (no requeridas) -sign-commit = false -sign-tag = false - -# Empuja etiquetas y commits -push = true - -# Publica en crates.io (puedes desactivarlo para pruebas) -publish = true - -# Solo permite publicar estos crates (los que forman parte del workspace) -allow-branch = ["main"] -consolidate-commits = false - -# Mensaje personalizado para el commit de versión -pre-release-commit-message = "🔖 Prepara publicación de {{crate_name}} {{version}}" - -pre-release-hook = [ - "sh", "-c", "ROOT=$(git rev-parse --show-toplevel) && \"$ROOT/tools/changelog.sh\" {{crate_name}} {{version}} --stage" -] diff --git a/.gitignore b/.gitignore index 65db440e..4ebc5a92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,4 @@ -# Ignora directorios de compilación **/target - -# Archivos de log **/log/*.log* - -# Archivos de configuración locales -**/local.*.toml -**/local.toml -.env +Cargo.lock +workdir diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index bfc9067a..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,86 +0,0 @@ -# CHANGELOG - -Este archivo documenta los cambios más relevantes realizados en cada versión. El formato está basado -en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/), y las versiones se numeran siguiendo -las reglas del [Versionado Semántico](https://semver.org/lang/es/). - -Resume la evolución del proyecto para usuarios y colaboradores, destacando nuevas funcionalidades, -correcciones, mejoras durante el desarrollo o cambios en la documentación. Cambios menores o -internos pueden omitirse si no afectan al uso del proyecto. - -## 0.4.0 (2025-09-20) - -### Añadido - -- [app] Añade manejo de rutas no encontradas -- [context] Añade métodos auxiliares de parámetros -- [util] Añade `indoc` para indentar código bien -- Añade componente `PoweredBy` para copyright - -### Cambiado - -- [html] Cambia tipos `Option...` por `Attr...` -- [html] Implementa `Default` en `Context` -- [welcome] Crea página de bienvenida desde intro -- [context] Generaliza los parámetros de contexto -- [context] Define un `trait` común de contexto -- Modifica tipos para atributos HTML a minúsculas -- Renombra `with_component` por `add_child` - -### Corregido - -- [welcome] Corrige giro botón con ancho estrecho -- [welcome] Corrige centrado del pie de página -- Corrige nombre de función en prueba de `Html` -- Corrige doc y código por cambios en Page - -### Dependencias - -- Actualiza dependencias para 0.4.0 - -### Documentado - -- [component] Amplía documentación de preparación -- Normaliza referencias al nombre PageTop -- Simplifica documentación de obsoletos -- Mejora la documentación de recursos y contexto - -### Otros cambios - -- 🎨 [theme] Mejora gestión de regiones en páginas -- ✅ [tests] Amplía pruebas para `PrepareMarkup' -- 🎨 [locale] Mejora el uso de `lookup` / `using` -- 🔨 [tools] Fuerza pulsar intro para confirmar input -- 💄 Aplica BEM a estilos de bienvenida y componente -- 🎨 Unifica conversiones a String con `to_string()` -- 🔥 Elimina `Render` para usar siempre el contexto - -## 0.3.0 (2025-08-16) - -### Cambiado - -- Redefine función para directorios absolutos -- Mejora la integración de archivos estáticos - -### Documentado - -- Cambia el formato para la documentación - -## 0.2.0 (2025-08-09) - -### Añadido - -- Añade librería para gestionar recursos estáticos -- Añade soporte a changelog de `pagetop-statics` - -### Documentado - -- Corrige enlace del botón de licencia en la documentación - -### Otros cambios - -- Afina Cargo.toml para buscar la mejor categoría - -## 0.1.0 (2025-08-06) - -- Versión inicial diff --git a/CREDITS.md b/CREDITS.md index c5a7bd2e..298295dc 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -1,33 +1,46 @@ -# 🔃 Dependencias +# ⌨️ Código -PageTop está basado en [Rust](https://www.rust-lang.org/) y crece a hombros de gigantes aprovechando -algunas de las librerías más robustas y populares del [ecosistema Rust](https://lib.rs) como son: +* PageTop incluye código de la versión [0.11.0](https://github.com/mehcode/config-rs/tree/0.11.0) de + [config](https://crates.io/crates/config), de [Ryan Leckey](https://crates.io/users/mehcode), por + las facilidades que ofrece frente a sus versiones más modernas para leer los ajustes de + configuración y delegar su asignación a tipos seguros según los requerimientos de cada módulo, + tema o aplicación. - * [Actix Web](https://actix.rs/) para los servicios web. - * [Config](https://docs.rs/config) para cargar y procesar las opciones de configuración. - * [Tracing](https://github.com/tokio-rs/tracing) para la gestión de trazas y registro de eventos - de la aplicación. - * [Fluent templates](https://github.com/XAMPPRocky/fluent-templates), que integra - [Fluent](https://projectfluent.org/) para internacionalizar las aplicaciones. - * Además de otros *crates* adicionales que se pueden explorar en los archivos `Cargo.toml` de - PageTop y sus extensiones. +* PageTop incorpora una versión adaptada del excelente *crate* [maud](https://crates.io/crates/maud) + de [Chris Wong](https://crates.io/users/lambda-fairy) (versión + [0.25.0](https://github.com/lambda-fairy/maud/tree/v0.25.0/maud)), para añadir sus funcionalidades + sin requerir la referencia a `maud` en el archivo `Cargo.toml` de cada proyecto. + +* PageTop usa los reconocidos *crates* [SQLx](https://github.com/launchbadge/sqlx) y + [SeaQuery](https://github.com/SeaQL/sea-query) para interactuar con bases de datos. Sin embargo, + para restringir las migraciones a módulos, se ha integrado en el código una versión modificada de + [SeaORM Migration](https://github.com/SeaQL/sea-orm/tree/master/sea-orm-migration) (versión + [0.11.3](https://github.com/SeaQL/sea-orm/tree/0.11.3/sea-orm-migration/src)). # 🗚 FIGfonts -PageTop usa el *crate* [figlet-rs](https://crates.io/crates/figlet-rs) desarrollado por *yuanbohan* -para mostrar un banner de presentación en el terminal con el nombre de la aplicación en caracteres -[FIGlet](http://www.figlet.org). Las fuentes incluidas en `pagetop/src/app` son: +PageTop utiliza el paquete [figlet-rs](https://crates.io/crates/figlet-rs) de *yuanbohan* para +mostrar en el terminal un rótulo de presentación con el nombre de la aplicación usando caracteres +[FIGlet](http://www.figlet.org). Las fuentes incluidas en `src/app` son: - * [slant.flf](http://www.figlet.org/fontdb_example.cgi?font=slant.flf) de *Glenn Chappell* - * [small.flf](http://www.figlet.org/fontdb_example.cgi?font=small.flf) de *Glenn Chappell* - (predeterminada) - * [speed.flf](http://www.figlet.org/fontdb_example.cgi?font=speed.flf) de *Claude Martins* - * [starwars.flf](http://www.figlet.org/fontdb_example.cgi?font=starwars.flf) de *Ryan Youck* +* [slant.flf](http://www.figlet.org/fontdb_example.cgi?font=slant.flf) por *Glenn Chappell*. +* [small.flf](http://www.figlet.org/fontdb_example.cgi?font=small.flf) por *Glenn Chappell* + (predeterminado). +* [speed.flf](http://www.figlet.org/fontdb_example.cgi?font=speed.flf) por *Claude Martins*. +* [starwars.flf](http://www.figlet.org/fontdb_example.cgi?font=starwars.flf) por *Ryan Youck*. + + +# 📰 Plantillas + +* El diseño de la página predeterminada de inicio está basado en la plantilla + [Zinc](https://themewagon.com/themes/free-bootstrap-5-html5-business-website-template-zinc) creada + por [inovatik](https://inovatik.com/) y distribuida por [ThemeWagon](https://themewagon.com). # 🎨 Icono -"La Criatura" sonriente es una simpática creación de [Webalys](https://www.iconfinder.com/webalys). -Forma parte de su colección [Nasty Icons](https://www.iconfinder.com/iconsets/nasty), disponible en -[ICONFINDER](https://www.iconfinder.com). +El monstruo sonriente de Frankenstein es una divertida creación de +[Webalys](https://www.iconfinder.com/webalys). Puede encontrarse en su colección +[Nasty Icons](https://www.iconfinder.com/iconsets/nasty) disponible en +[ICONFINDER](https://www.iconfinder.com). \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 2f9fa42e..00000000 --- a/Cargo.lock +++ /dev/null @@ -1,3123 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "actix-codec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-files" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c0d87f10d70e2948ad40e8edea79c8e77c6c66e0250a4c1f09b690465199576" -dependencies = [ - "actix-http", - "actix-service", - "actix-utils", - "actix-web", - "bitflags", - "bytes", - "derive_more 2.0.1", - "futures-core", - "http-range", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "v_htmlescape", -] - -[[package]] -name = "actix-http" -version = "3.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7926860314cbe2fb5d1f13731e387ab43bd32bca224e82e6e2db85de0a3dba49" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "base64 0.22.1", - "bitflags", - "brotli", - "bytes", - "bytestring", - "derive_more 2.0.1", - "encoding_rs", - "flate2", - "foldhash", - "futures-core", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand 0.9.2", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "actix-router" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" -dependencies = [ - "bytestring", - "cfg-if", - "http", - "regex", - "regex-lite", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92589714878ca59a7626ea19734f0e07a6a875197eec751bb5d3f99e64998c63" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65064ea4a457eaf07f2fba30b4c695bf43b721790e9530d26cb6f9019ff7502" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2 0.5.10", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "actix-session" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "400c27fd4cdbe0082b7bbd29ac44a3070cbda1b2114138dc106ba39fe2f90dff" -dependencies = [ - "actix-service", - "actix-utils", - "actix-web", - "anyhow", - "derive_more 2.0.1", - "rand 0.9.2", - "serde", - "serde_json", - "tracing", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a597b77b5c6d6a1e1097fddde329a83665e25c5437c696a3a9a4aa514a614dea" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "bytes", - "bytestring", - "cfg-if", - "cookie", - "derive_more 2.0.1", - "encoding_rs", - "foldhash", - "futures-core", - "futures-util", - "impl-more", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "regex-lite", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2 0.5.10", - "time", - "tracing", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" -dependencies = [ - "windows-sys 0.60.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.60.2", -] - -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", -] - -[[package]] -name = "base64" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "brotli" -version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bstr" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "bytestring" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113b4343b5f6617e7ad401ced8de3cc8b012e73a594347c307b90db3e9271289" -dependencies = [ - "bytes", -] - -[[package]] -name = "cc" -version = "1.2.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" - -[[package]] -name = "change-detection" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "159fa412eae48a1d94d0b9ecdb85c97ce56eb2a347c62394d3fdbf221adabc1a" -dependencies = [ - "path-matchers", - "path-slash 0.1.5", -] - -[[package]] -name = "chrono" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "4.5.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.5.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" - -[[package]] -name = "codemap" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24" - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[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 = "concat-string" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7439becb5fafc780b6f4de382b1a7a3e70234afe783854a4702ee8adbb838609" - -[[package]] -name = "config" -version = "0.15.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e549344080374f9b32ed41bf3b6b57885ff6a289367b3dbc10eea8acc1918" -dependencies = [ - "pathdiff", - "serde_core", - "toml", - "winnow", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "aes-gcm", - "base64 0.20.0", - "hkdf", - "hmac", - "percent-encoding", - "rand 0.8.5", - "sha2", - "subtle", - "time", - "version_check", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "deranged" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", -] - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "figlet-rs" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4742a071cd9694fc86f9fa1a08fa3e53d40cc899d7ee532295da2d085639fbc5" - -[[package]] -name = "find-msvc-tools" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" - -[[package]] -name = "flate2" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fluent-bundle" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4" -dependencies = [ - "fluent-langneg", - "fluent-syntax", - "intl-memoizer", - "intl_pluralrules", - "rustc-hash", - "self_cell", - "smallvec", - "unic-langid", -] - -[[package]] -name = "fluent-langneg" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94" -dependencies = [ - "unic-langid", -] - -[[package]] -name = "fluent-syntax" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198" -dependencies = [ - "memchr", - "thiserror 2.0.17", -] - -[[package]] -name = "fluent-template-macros" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6222b8a208b9f0e7b984da3616651b0cc74e4461571b118cb1c713e0f7617ee" -dependencies = [ - "flume", - "ignore", - "proc-macro2", - "quote", - "syn", - "unic-langid", -] - -[[package]] -name = "fluent-templates" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a893d77c0e48dc3f78421e9cba5d82e02bcb85d4520c506cec2fbebd0f513b" -dependencies = [ - "fluent-bundle", - "fluent-langneg", - "fluent-syntax", - "fluent-template-macros", - "flume", - "ignore", - "intl-memoizer", - "log", - "thiserror 1.0.69", - "unic-langid", -] - -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "spin", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.7+wasi-0.2.4", -] - -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "globset" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "grass" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7a68216437ef68f0738e48d6c7bb9e6e6a92237e001b03d838314b068f33c94" -dependencies = [ - "clap", - "getrandom 0.2.16", - "grass_compiler", -] - -[[package]] -name = "grass_compiler" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d9e3df7f0222ce5184154973d247c591d9aadc28ce7a73c6cd31100c9facff6" -dependencies = [ - "codemap", - "indexmap", - "lasso", - "once_cell", - "phf", - "rand 0.8.5", -] - -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-range" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "iana-time-zone" -version = "0.1.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "ignore" -version = "0.4.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "impl-more" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" - -[[package]] -name = "indexmap" -version = "2.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" -dependencies = [ - "equivalent", - "hashbrown 0.16.0", -] - -[[package]] -name = "indoc" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "intl-memoizer" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f" -dependencies = [ - "type-map", - "unic-langid", -] - -[[package]] -name = "intl_pluralrules" -version = "7.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" -dependencies = [ - "unic-langid", -] - -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - -[[package]] -name = "lasso" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e14eda50a3494b3bf7b9ce51c52434a761e383d7238ce1dd5dcec2fbc13e9fb" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "local-channel" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "log", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "mutually_exclusive_features" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94e1e6445d314f972ff7395df2de295fe51b71821694f0b0e1e79c4f12c8577" - -[[package]] -name = "nu-ansi-term" -version = "0.50.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "pagetop" -version = "0.4.0" -dependencies = [ - "actix-files", - "actix-session", - "actix-web", - "chrono", - "colored", - "concat-string", - "config", - "figlet-rs", - "fluent-templates", - "indoc", - "itoa", - "pagetop-aliner", - "pagetop-bootsier", - "pagetop-build", - "pagetop-macros", - "pagetop-statics", - "parking_lot", - "pastey", - "serde", - "serde_json", - "substring", - "tempfile", - "terminal_size", - "tracing", - "tracing-actix-web", - "tracing-appender", - "tracing-subscriber", - "unic-langid", -] - -[[package]] -name = "pagetop-aliner" -version = "0.0.9" -dependencies = [ - "pagetop", - "pagetop-build", -] - -[[package]] -name = "pagetop-bootsier" -version = "0.0.18" -dependencies = [ - "pagetop", - "pagetop-build", - "serde", -] - -[[package]] -name = "pagetop-build" -version = "0.3.1" -dependencies = [ - "grass", - "pagetop-statics", -] - -[[package]] -name = "pagetop-macros" -version = "0.2.0" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn", -] - -[[package]] -name = "pagetop-statics" -version = "0.1.2" -dependencies = [ - "actix-web", - "change-detection", - "derive_more 0.99.20", - "futures-util", - "mime_guess", - "path-slash 0.2.1", -] - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pastey" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" - -[[package]] -name = "path-matchers" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36cd9b72a47679ec193a5f0229d9ab686b7bd45e1fbc59ccf953c9f3d83f7b2b" -dependencies = [ - "glob", -] - -[[package]] -name = "path-slash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498a099351efa4becc6a19c72aa9270598e8fd274ca47052e37455241c88b696" - -[[package]] -name = "path-slash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "potential_utf" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - -[[package]] -name = "proc-macro2" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-lite" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" - -[[package]] -name = "regex-syntax" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" - -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "self_cell" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749" - -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "serde_spanned" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" -dependencies = [ - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "substring" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" -dependencies = [ - "autocfg", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tempfile" -version = "3.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "terminal_size" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" -dependencies = [ - "rustix", - "windows-sys 0.60.2", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl 2.0.17", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "time" -version = "0.3.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" - -[[package]] -name = "time-macros" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.47.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" -dependencies = [ - "backtrace", - "bytes", - "io-uring", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "slab", - "socket2 0.6.0", - "windows-sys 0.59.0", -] - -[[package]] -name = "tokio-util" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" -dependencies = [ - "serde_core", - "serde_spanned", - "toml_datetime", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml_datetime" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_parser" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" -dependencies = [ - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-actix-web" -version = "0.7.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5360edd490ec8dee9fedfc6a9fd83ac2f01b3e1996e3261b9ad18a61971fe064" -dependencies = [ - "actix-web", - "mutually_exclusive_features", - "pin-project", - "tracing", - "uuid", -] - -[[package]] -name = "tracing-appender" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" -dependencies = [ - "crossbeam-channel", - "thiserror 1.0.69", - "time", - "tracing-subscriber", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "type-map" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" -dependencies = [ - "rustc-hash", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unic-langid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05" -dependencies = [ - "unic-langid-impl", - "unic-langid-macros", -] - -[[package]] -name = "unic-langid-impl" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658" -dependencies = [ - "tinystr", -] - -[[package]] -name = "unic-langid-macros" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5957eb82e346d7add14182a3315a7e298f04e1ba4baac36f7f0dbfedba5fc25" -dependencies = [ - "proc-macro-hack", - "tinystr", - "unic-langid-impl", - "unic-langid-macros-impl", -] - -[[package]] -name = "unic-langid-macros-impl" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5" -dependencies = [ - "proc-macro-hack", - "quote", - "syn", - "unic-langid-impl", -] - -[[package]] -name = "unicase" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" - -[[package]] -name = "unicode-ident" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "1.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" -dependencies = [ - "getrandom 0.3.3", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "v_htmlescape" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index b1bae0a6..2029180c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,90 +1,27 @@ -[package] -name = "pagetop" -version = "0.4.0" -edition = "2021" - -description = """ - Un entorno de desarrollo para crear soluciones web modulares, extensibles y configurables. -""" -categories = ["web-programming::http-server"] -keywords = ["pagetop", "web", "framework", "frontend", "ssr"] - -repository.workspace = true -homepage.workspace = true -license.workspace = true -authors.workspace = true - -[dependencies] -chrono = "0.4" -colored = "3.0" -concat-string = "1.0" -config = { version = "0.15", default-features = false, features = ["toml"] } -figlet-rs = "0.1" -indoc = "2.0" -itoa = "1.0" -parking_lot = "0.12" -paste = { package = "pastey", version = "0.1" } -substring = "1.4" -terminal_size = "0.4" - -tracing = "0.1" -tracing-appender = "0.2" -tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] } -tracing-actix-web = "0.7" - -fluent-templates = "0.13" -unic-langid = { version = "0.9", features = ["macros"] } - -actix-web = { workspace = true, default-features = true } -actix-session = { version = "0.11", features = ["cookie-session"] } -actix-web-files = { package = "actix-files", version = "0.6" } - -serde.workspace = true - -pagetop-macros.workspace = true -pagetop-statics.workspace = true - -[features] -default = [] -testing = [] - -[dev-dependencies] -tempfile = "3.23" -serde_json = "1.0" -pagetop-aliner.workspace = true -pagetop-bootsier.workspace = true - -[build-dependencies] -pagetop-build.workspace = true - - [workspace] -resolver = "2" + members = [ - # Helpers - "helpers/pagetop-build", - "helpers/pagetop-macros", - "helpers/pagetop-statics", - # Extensions - "extensions/pagetop-aliner", - "extensions/pagetop-bootsier", + "pagetop", + # Utilities. + "pagetop-macros", + "pagetop-build", + "pagetop-jquery", + "pagetop-homedemo", + # Components. + "pagetop-minimal", + "pagetop-megamenu", + # Modules. + "pagetop-admin", + "pagetop-user", + "pagetop-node", + # Themes. + "pagetop-aliner", + "pagetop-bootsier", + "pagetop-bulmix", ] -[workspace.package] -repository = "https://git.cillero.es/manuelcillero/pagetop" -homepage = "https://pagetop.cillero.es" -license = "MIT OR Apache-2.0" -authors = ["Manuel Cillero "] - -[workspace.dependencies] -actix-web = { version = "4.11", default-features = false } -serde = { version = "1.0", features = ["derive"] } -# Helpers -pagetop-build = { version = "0.3", path = "helpers/pagetop-build" } -pagetop-macros = { version = "0.2", path = "helpers/pagetop-macros" } -pagetop-statics = { version = "0.1", path = "helpers/pagetop-statics" } -# Extensions -pagetop-aliner = { version = "0.0", path = "extensions/pagetop-aliner" } -pagetop-bootsier = { version = "0.0", path = "extensions/pagetop-bootsier" } -# PageTop -pagetop = { version = "0.4", path = "." } +exclude = [ + "drust", + "examples", + "tests", +] diff --git a/README.md b/README.md index 9a12c845..cfc3abcd 100644 --- a/README.md +++ b/README.md @@ -1,151 +1,105 @@
- + -

PageTop

+

PageTop

-

Un entorno para el desarrollo de soluciones web modulares, extensibles y configurables.

+ [![crate](https://img.shields.io/crates/v/pagetop.svg)](https://crates.io/crates/pagetop) + [![docs](https://docs.rs/pagetop/badge.svg)](https://docs.rs/pagetop) -[![Doc API](https://img.shields.io/docsrs/pagetop?label=Doc%20API&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop) -[![Crates.io](https://img.shields.io/crates/v/pagetop.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop) -[![Descargas](https://img.shields.io/crates/d/pagetop.svg?label=Descargas&style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop) -[![Licencia](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label=Licencia&style=for-the-badge)](https://git.cillero.es/manuelcillero/pagetop#licencia) - -
-PageTop reivindica la esencia de la web clásica usando [Rust](https://www.rust-lang.org/es) para la -creación de soluciones web SSR (*renderizadas en el servidor*) basadas en HTML, CSS y JavaScript. -Ofrece un conjunto de herramientas que los desarrolladores pueden implementar, extender o adaptar -según las necesidades de cada proyecto, incluyendo: +**PageTop** es un entorno de desarrollo basado en [Rust](https://www.rust-lang.org/es/) que reúne +algunos de los crates más estables y populares para crear soluciones web modulares, extensibles y +configurables. - * **Acciones** (*actions*): alteran la lógica interna de una funcionalidad interceptando su flujo - de ejecución. - * **Componentes** (*components*): encapsulan HTML, CSS y JavaScript en unidades funcionales, - configurables y reutilizables. - * **Extensiones** (*extensions*): añaden, extienden o personalizan funcionalidades usando las APIs - de PageTop o de terceros. - * **Temas** (*themes*): son extensiones que permiten modificar la apariencia de páginas y - componentes sin comprometer su funcionalidad. - - -# ⚡️ Guía rápida - -La aplicación más sencilla de PageTop se ve así: - -```rust,no_run -use pagetop::prelude::*; - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::new().run()?.await -} -``` - -Este código arranca el servidor de PageTop. Con la configuración por defecto, muestra una página de -bienvenida accesible desde un navegador local en la dirección `http://localhost:8080`. - -Para personalizar el servicio, se puede crear una extensión de PageTop de la siguiente manera: - -```rust,no_run -use pagetop::prelude::*; - -struct HelloWorld; - -impl Extension for HelloWorld { - fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { - scfg.route("/", service::web::get().to(hello_world)); - } -} - -async fn hello_world(request: HttpRequest) -> ResultPage { - Page::new(request) - .add_child(Html::with(|_| html! { h1 { "Hello World!" } })) - .render() -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&HelloWorld).run()?.await -} -``` - -Este programa implementa una extensión llamada `HelloWorld` que sirve una página web en la ruta raíz -(`/`) mostrando el texto "Hello world!" dentro de un elemento HTML `

`. - - -# 📂 Repositorio - -El código se organiza en un *workspace* donde actualmente se incluyen los siguientes subproyectos: - - * **[pagetop](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/src)**, con el código - fuente de la librería principal. Reúne algunos de los *crates* más estables y populares del - ecosistema Rust para proporcionar APIs y recursos para la creación avanzada de soluciones web. - -## Auxiliares - - * **[pagetop-statics](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-statics)**, - es la librería que permite incluir archivos estáticos en el ejecutable de las aplicaciones - PageTop para servirlos de forma eficiente, con detección de cambios que optimizan el tiempo de - compilación. - - * **[pagetop-build](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-build)**, - prepara los archivos estáticos o archivos SCSS compilados para incluirlos en el binario de las - aplicaciones PageTop durante la compilación de los ejecutables. - - * **[pagetop-macros](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-macros)**, - proporciona una colección de macros que mejoran la experiencia de desarrollo con PageTop. - -## Extensiones - - * **[pagetop-aliner](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner)**, - es un tema para demos y pruebas que muestra esquemáticamente la composición de las páginas HTML. - - * **[pagetop-bootsier](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-bootsier)**, - tema basado en [Bootstrap](https://getbootstrap.com) para integrar su catálogo de estilos y - componentes flexibles. - - -# 🧪 Pruebas - -Para simplificar el flujo de trabajo, el repositorio incluye varios **alias de Cargo** declarados en -`.cargo/config.toml`. Basta con ejecutarlos desde la raíz del proyecto: - -| Comando | Descripción | -| ------- | ----------- | -| `cargo ts` | Ejecuta los tests de `pagetop` (*unit + integration*) con la *feature* `testing`. | -| `cargo ts --test util` | Lanza sólo las pruebas de integración del módulo `util`. | -| `cargo ts --doc locale` | Lanza las pruebas de la documentación del módulo `locale`. | -| `cargo tw` | Ejecuta los tests de **todos los paquetes** del *workspace*. | - -> **Nota** -> Estos alias ya compilan con la configuración adecuada. No requieren `--no-default-features`. -> Si quieres **activar** las trazas del registro de eventos entonces usa simplemente `cargo test`. +Incluye **Drust**, un sistema de gestión de contenidos basado en PageTop que permite crear, editar y +mantener sitios web dinámicos, rápidos y seguros. # 🚧 Advertencia -**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su -ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos -hasta que se libere la versión **1.0.0**. +**PageTop** es un proyecto personal para aprender Rust y conocer su ecosistema. Sólo se liberan +versiones de desarrollo. En este contexto la API no es estable y los cambios son constantes. No +puede considerarse preparado hasta que se libere la versión **0.1.0**. + + +# 📂 Estructura del código + +El repositorio se organiza en un *workspace* con los siguientes subproyectos: + +* **[pagetop](https://github.com/manuelcillero/pagetop/tree/main/pagetop)**, es la librería esencial + construida con *crates* estables y muy conocidos del ecosistema Rust para proporcionar APIs, + patrones de desarrollo y buenas prácticas para la creación avanzada de soluciones web SSR + (*Server-Side Rendering*). + +## Auxiliares + +* **[pagetop-macros](https://github.com/manuelcillero/pagetop/tree/main/pagetop-macros)**, agrupa + las principales macros procedurales para usar desde **PageTop**. + +* **[pagetop-build](https://github.com/manuelcillero/pagetop/tree/main/pagetop-build)**, permite + incluir fácilmente recursos en los archivos binarios al compilar aplicaciones creadas con + **PageTop**. + +## Componentes + +* **[pagetop-minimal](https://github.com/manuelcillero/pagetop/tree/main/pagetop-minimal)**, módulo + que proporciona un conjunto básico de componentes para la composición de páginas. + +* **[pagetop-jquery](https://github.com/manuelcillero/pagetop/tree/main/pagetop-jquery)**, módulo + que permite añadir jQuery en las páginas que incluyen componentes o temas que usen esta librería + JavaScript para interactuar con el documento HTML.​ + +* **[pagetop-megamenu](https://github.com/manuelcillero/pagetop/tree/main/pagetop-megamenu)**, + módulo que proporciona un nuevo componente para incluir menús avanzados en las aplicaciones web + creadas con **PageTop**. + +## Módulos + +* **[pagetop-homedemo](https://github.com/manuelcillero/pagetop/tree/main/pagetop-homedemo)**, + módulo que muestra una página de inicio de demostración para presentar **PageTop**. + +* **[pagetop-admin](https://github.com/manuelcillero/pagetop/tree/main/pagetop-admin)**, módulo que + proporciona a otros módulos un lugar común donde presentar a los administradores sus opciones de + configuración. + +* **[pagetop-user](https://github.com/manuelcillero/pagetop/tree/main/pagetop-user)**, módulo para + añadir gestión de usuarios, roles, permisos y sesiones en aplicaciones desarrolladas con PageTop. + +* **[pagetop-node](https://github.com/manuelcillero/pagetop/tree/main/pagetop-node)**, módulo para + crear, extender o personalizar los tipos de contenido que puede administrar un sitio web. + +## Temas + +* **[pagetop-aliner](https://github.com/manuelcillero/pagetop/tree/main/pagetop-aliner)**, tema que + delimita con cajas los elementos HTML para mostrar esquemáticamente la composición de las páginas. + +* **[pagetop-bootsier](https://github.com/manuelcillero/pagetop/tree/main/pagetop-bootsier)**, tema + que utiliza el *framework* [Bootstrap](https://getbootstrap.com/) para la composición de páginas y + visualización de componentes. + +* **[pagetop-bulmix](https://github.com/manuelcillero/pagetop/tree/main/pagetop-bulmix)**, tema que + utiliza el *framework* [Bulma](https://bulma.io/) para la composición de páginas y visualización + de componentes. + +## Aplicación + +* **[drust](https://github.com/manuelcillero/pagetop/tree/main/drust)**, es una aplicación + inspirada modestamente en [Drupal](https://www.drupal.org) que utiliza PageTop para crear un CMS + (*Content Management System* o sistema de gestión de contenidos) para construir sitios web + dinámicos, administrados y configurables. # 📜 Licencia -El código está disponible bajo una doble licencia: +Este proyecto tiene licencia, de hecho tiene dos, puedes aplicar cualquiera de las siguientes a tu +elección: - * **Licencia MIT** - ([LICENSE-MIT](LICENSE-MIT) o también https://opensource.org/licenses/MIT) +* Licencia Apache versión 2.0 + ([LICENSE-APACHE](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-APACHE) o + [http://www.apache.org/licenses/LICENSE-2.0]). - * **Licencia Apache, Versión 2.0** - ([LICENSE-APACHE](LICENSE-APACHE) o también https://www.apache.org/licenses/LICENSE-2.0) - -Puedes elegir la licencia que prefieras. Este enfoque de doble licencia es el estándar de facto en -el ecosistema Rust. - - -# ✨ Contribuir - -Cualquier contribución para añadir al proyecto se considerará automáticamente bajo la doble licencia -indicada arriba (MIT o Apache v2.0), sin términos o condiciones adicionales, tal y como permite la -licencia *Apache v2.0*. +* Licencia MIT + ([LICENSE-MIT](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-MIT) o + [http://opensource.org/licenses/MIT]). diff --git a/banner-pagetop.png b/banner-pagetop.png new file mode 100644 index 00000000..3ad51741 Binary files /dev/null and b/banner-pagetop.png differ diff --git a/config/default.toml b/config/default.toml deleted file mode 100644 index 3e254586..00000000 --- a/config/default.toml +++ /dev/null @@ -1,2 +0,0 @@ -[log] -tracing = "Info,pagetop=Debug" diff --git a/drust/Cargo.toml b/drust/Cargo.toml new file mode 100644 index 00000000..c0de9ab6 --- /dev/null +++ b/drust/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "drust" +version = "0.0.3" +edition = "2021" + +authors = [ + "Manuel Cillero " +] +description = """\ + A modern web Content Management System to share your world.\ +""" +homepage = "https://pagetop.cillero.es" +repository = "https://github.com/manuelcillero/pagetop" +license = "Apache-2.0 OR MIT" + +[dependencies] +pagetop = { version = "0.0", path = "../pagetop", features = ["mysql"], default-features = false } +# Themes. +pagetop-aliner = { version = "0.0", path = "../pagetop-aliner" } +pagetop-bootsier = { version = "0.0", path = "../pagetop-bootsier" } +pagetop-bulmix = { version = "0.0", path = "../pagetop-bulmix" } +# Modules. +pagetop-homedemo = { version = "0.0", path = "../pagetop-homedemo" } +pagetop-admin = { version = "0.0", path = "../pagetop-admin" } +pagetop-user = { version = "0.0", path = "../pagetop-user" } +pagetop-node = { version = "0.0", path = "../pagetop-node" } diff --git a/drust/README.md b/drust/README.md new file mode 100644 index 00000000..25431d18 --- /dev/null +++ b/drust/README.md @@ -0,0 +1,28 @@ +**Drust** es una aplicación inspirada modestamente en [Drupal](https://www.drupal.org) que utiliza +**PageTop** para crear un CMS (*Content Management System* o sistema de gestión de contenidos) para +construir sitios web dinámicos, administrados y configurables. + +[PageTop](https://github.com/manuelcillero/pagetop/tree/main/pagetop), es un entorno de desarrollo +basado en algunos de los *crates* más estables y populares del ecosistema Rust para proporcionar +APIs, patrones de desarrollo y buenas prácticas para la creación de soluciones web SSR (*Server-Side +Rendering*). + + +# 🚧 Advertencia + +**PageTop** sólo libera actualmente versiones de desarrollo. La API no es estable y los cambios son +constantes. No puede considerarse preparado hasta que se libere la versión **0.1.0**. + + +# 📜 Licencia + +Este proyecto tiene licencia, de hecho tiene dos, puedes aplicar cualquiera de las siguientes a tu +elección: + +* Licencia Apache versión 2.0 + ([LICENSE-APACHE](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-APACHE) o + [http://www.apache.org/licenses/LICENSE-2.0]). + +* Licencia MIT + ([LICENSE-MIT](https://github.com/manuelcillero/pagetop/blob/main/LICENSE-MIT) o + [http://opensource.org/licenses/MIT]). diff --git a/drust/config/common.toml b/drust/config/common.toml new file mode 100644 index 00000000..1562e469 --- /dev/null +++ b/drust/config/common.toml @@ -0,0 +1,8 @@ +[app] +name = "Drust" +description = """\ + A modern web Content Management System to share your world.\ +""" + +[database] +db_type = "mysql" diff --git a/drust/config/default.toml b/drust/config/default.toml new file mode 100644 index 00000000..1cbcbfea --- /dev/null +++ b/drust/config/default.toml @@ -0,0 +1,4 @@ +[database] +db_name = "drust" +db_user = "drust" +db_pass = "DrU__#3T" diff --git a/drust/config/local.toml b/drust/config/local.toml new file mode 100644 index 00000000..410a913d --- /dev/null +++ b/drust/config/local.toml @@ -0,0 +1,12 @@ +[app] +#theme = "Default" +#theme = "Aliner" +theme = "Bootsier" +#theme = "Bulmix" +language = "es-ES" + +[log] +tracing = "Info,pagetop=Debug,sqlx::query=Warn" + +[dev] +#static_files = "../pagetop/static" diff --git a/drust/src/main.rs b/drust/src/main.rs new file mode 100644 index 00000000..306b3c02 --- /dev/null +++ b/drust/src/main.rs @@ -0,0 +1,36 @@ +use pagetop::prelude::*; + +new_handle!(APP_DRUST); + +struct Drust; + +impl ModuleTrait for Drust { + fn handle(&self) -> Handle { + APP_DRUST + } + + fn dependencies(&self) -> Vec { + vec![ + // Themes. + &pagetop_aliner::Aliner, + &pagetop_bootsier::Bootsier, + &pagetop_bulmix::Bulmix, + // Modules. + &pagetop_homedemo::HomeDemo, + &pagetop_admin::Admin, + &pagetop_user::User, + &pagetop_node::Node, + ] + } + + fn drop_modules(&self) -> Vec { + vec![ + // &pagetop_node::Node + ] + } +} + +#[pagetop::main] +async fn main() -> std::io::Result<()> { + Application::prepare(&Drust).unwrap().run()?.await +} diff --git a/examples/Cargo.toml b/examples/Cargo.toml new file mode 100644 index 00000000..167bbef8 --- /dev/null +++ b/examples/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = [ + "basics/*", +] diff --git a/examples/app-basic.rs b/examples/app-basic.rs deleted file mode 100644 index 53743870..00000000 --- a/examples/app-basic.rs +++ /dev/null @@ -1,6 +0,0 @@ -use pagetop::prelude::*; - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::new().run()?.await -} diff --git a/examples/basics/hello-name/Cargo.toml b/examples/basics/hello-name/Cargo.toml new file mode 100644 index 00000000..6b41c11b --- /dev/null +++ b/examples/basics/hello-name/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "hello_name" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +actix-web = "4" +pagetop = { version = "0.0", path = "../../../pagetop" } diff --git a/examples/basics/hello-name/src/main.rs b/examples/basics/hello-name/src/main.rs new file mode 100644 index 00000000..0af7c2d0 --- /dev/null +++ b/examples/basics/hello-name/src/main.rs @@ -0,0 +1,31 @@ +use pagetop::prelude::*; + +new_handle!(APP_HELLO_NAME); + +struct HelloName; + +impl ModuleTrait for HelloName { + fn handle(&self) -> Handle { + APP_HELLO_NAME + } + + fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { + scfg.service(hello_name); + } +} + +#[service::get("/hello/{name}")] +async fn hello_name( + request: service::HttpRequest, + path: service::web::Path, +) -> ResultPage { + let name = path.into_inner(); + Page::new(request) + .with_in("content", Html::with(html! { h1 { "Hello " (name) "!" } })) + .render() +} + +#[pagetop::main] +async fn main() -> std::io::Result<()> { + Application::prepare(&HelloName).unwrap().run()?.await +} diff --git a/examples/basics/hello-world/Cargo.toml b/examples/basics/hello-world/Cargo.toml new file mode 100644 index 00000000..517f6a10 --- /dev/null +++ b/examples/basics/hello-world/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_world" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +pagetop = { version = "0.0", path = "../../../pagetop" } diff --git a/examples/basics/hello-world/src/main.rs b/examples/basics/hello-world/src/main.rs new file mode 100644 index 00000000..176c7304 --- /dev/null +++ b/examples/basics/hello-world/src/main.rs @@ -0,0 +1,26 @@ +use pagetop::prelude::*; + +new_handle!(APP_HELLO_WORLD); + +struct HelloWorld; + +impl ModuleTrait for HelloWorld { + fn handle(&self) -> Handle { + APP_HELLO_WORLD + } + + fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { + scfg.route("/", service::web::get().to(hello_world)); + } +} + +async fn hello_world(request: service::HttpRequest) -> ResultPage { + Page::new(request) + .with_in("content", Html::with(html! { h1 { "Hello World!" } })) + .render() +} + +#[pagetop::main] +async fn main() -> std::io::Result<()> { + Application::prepare(&HelloWorld).unwrap().run()?.await +} diff --git a/examples/hello-name.rs b/examples/hello-name.rs deleted file mode 100644 index c6a82aaf..00000000 --- a/examples/hello-name.rs +++ /dev/null @@ -1,24 +0,0 @@ -use pagetop::prelude::*; - -struct HelloName; - -impl Extension for HelloName { - fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { - scfg.route("/hello/{name}", service::web::get().to(hello_name)); - } -} - -async fn hello_name( - request: HttpRequest, - path: service::web::Path, -) -> ResultPage { - let name = path.into_inner(); - Page::new(request) - .add_child(Html::with(move |_| html! { h1 { "Hello " (name) "!" } })) - .render() -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&HelloName).run()?.await -} diff --git a/examples/hello-world.rs b/examples/hello-world.rs deleted file mode 100644 index 64817466..00000000 --- a/examples/hello-world.rs +++ /dev/null @@ -1,20 +0,0 @@ -use pagetop::prelude::*; - -struct HelloWorld; - -impl Extension for HelloWorld { - fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { - scfg.route("/", service::web::get().to(hello_world)); - } -} - -async fn hello_world(request: HttpRequest) -> ResultPage { - Page::new(request) - .add_child(Html::with(|_| html! { h1 { "Hello World!" } })) - .render() -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&HelloWorld).run()?.await -} diff --git a/examples/navbar-menus.rs b/examples/navbar-menus.rs deleted file mode 100644 index 341d394a..00000000 --- a/examples/navbar-menus.rs +++ /dev/null @@ -1,109 +0,0 @@ -use pagetop::prelude::*; - -use pagetop_bootsier::prelude::*; - -struct SuperMenu; - -impl Extension for SuperMenu { - fn dependencies(&self) -> Vec { - vec![&pagetop_aliner::Aliner, &pagetop_bootsier::Bootsier] - } - - fn initialize(&self) { - let home_path = |cx: &Context| match cx.langid().language.as_str() { - "en" => "/en", - _ => "/", - }; - - let navbar_menu = Navbar::brand_left(navbar::Brand::new().with_path(Some(home_path))) - .with_expand(BreakPoint::LG) - .add_item(navbar::Item::nav( - Nav::new() - .add_item(nav::Item::link( - L10n::l("sample_menus_item_link"), - home_path, - )) - .add_item(nav::Item::link_blank( - L10n::l("sample_menus_item_blank"), - |_| "https://docs.rs/pagetop", - )) - .add_item(nav::Item::dropdown( - Dropdown::new() - .with_title(L10n::l("sample_menus_test_title")) - .add_item(dropdown::Item::header(L10n::l("sample_menus_dev_header"))) - .add_item(dropdown::Item::link( - L10n::l("sample_menus_dev_getting_started"), - |_| "/dev/getting-started", - )) - .add_item(dropdown::Item::link( - L10n::l("sample_menus_dev_guides"), - |_| "/dev/guides", - )) - .add_item(dropdown::Item::link_blank( - L10n::l("sample_menus_dev_forum"), - |_| "https://forum.example.dev", - )) - .add_item(dropdown::Item::divider()) - .add_item(dropdown::Item::header(L10n::l("sample_menus_sdk_header"))) - .add_item(dropdown::Item::link( - L10n::l("sample_menus_sdk_rust"), - |_| "/dev/sdks/rust", - )) - .add_item(dropdown::Item::link(L10n::l("sample_menus_sdk_js"), |_| { - "/dev/sdks/js" - })) - .add_item(dropdown::Item::link( - L10n::l("sample_menus_sdk_python"), - |_| "/dev/sdks/python", - )) - .add_item(dropdown::Item::divider()) - .add_item(dropdown::Item::header(L10n::l( - "sample_menus_plugin_header", - ))) - .add_item(dropdown::Item::link( - L10n::l("sample_menus_plugin_auth"), - |_| "/dev/sdks/rust/plugins/auth", - )) - .add_item(dropdown::Item::link( - L10n::l("sample_menus_plugin_cache"), - |_| "/dev/sdks/rust/plugins/cache", - )) - .add_item(dropdown::Item::divider()) - .add_item(dropdown::Item::label(L10n::l("sample_menus_item_label"))) - .add_item(dropdown::Item::link_disabled( - L10n::l("sample_menus_item_disabled"), - |_| "#", - )), - )) - .add_item(nav::Item::link_disabled( - L10n::l("sample_menus_item_disabled"), - |_| "#", - )), - )) - .add_item(navbar::Item::nav( - Nav::new() - .with_classes( - ClassesOp::Add, - classes::Margin::with(Side::Start, ScaleSize::Auto).to_class(), - ) - .add_item(nav::Item::link( - L10n::l("sample_menus_item_sign_up"), - |_| "/auth/sign-up", - )) - .add_item(nav::Item::link(L10n::l("sample_menus_item_login"), |_| { - "/auth/login" - })), - )); - - InRegion::Named("header").add(Child::with( - Container::new() - .with_width(container::Width::FluidMax(UnitValue::RelRem(75.0))) - .add_child(navbar_menu), - )); - } -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&SuperMenu).run()?.await -} diff --git a/extensions/pagetop-aliner/Cargo.toml b/extensions/pagetop-aliner/Cargo.toml deleted file mode 100644 index 603a6309..00000000 --- a/extensions/pagetop-aliner/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "pagetop-aliner" -version = "0.0.9" -edition = "2021" - -description = """ - Tema de PageTop que muestra esquemáticamente la composición de las páginas HTML -""" -categories = ["web-programming", "gui"] -keywords = ["pagetop", "theme", "css"] - -repository.workspace = true -homepage.workspace = true -license.workspace = true -authors.workspace = true - -[dependencies] -pagetop.workspace = true - -[build-dependencies] -pagetop-build.workspace = true diff --git a/extensions/pagetop-aliner/LICENSE-APACHE b/extensions/pagetop-aliner/LICENSE-APACHE deleted file mode 100644 index 263ddac1..00000000 --- a/extensions/pagetop-aliner/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 Manuel Cillero - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/extensions/pagetop-aliner/LICENSE-MIT b/extensions/pagetop-aliner/LICENSE-MIT deleted file mode 100644 index cd8af3d6..00000000 --- a/extensions/pagetop-aliner/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Manuel Cillero - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/extensions/pagetop-aliner/README.md b/extensions/pagetop-aliner/README.md deleted file mode 100644 index f4670aae..00000000 --- a/extensions/pagetop-aliner/README.md +++ /dev/null @@ -1,101 +0,0 @@ -
- -

PageTop Aliner

- -

Tema de PageTop que muestra esquemáticamente la composición de las páginas HTML.

- -[![Doc API](https://img.shields.io/docsrs/pagetop-aliner?label=Doc%20API&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-aliner) -[![Crates.io](https://img.shields.io/crates/v/pagetop-aliner.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop-aliner) -[![Descargas](https://img.shields.io/crates/d/pagetop-aliner.svg?label=Descargas&style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop-aliner) -[![Licencia](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label=Licencia&style=for-the-badge)](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner#licencia) - -
-
- -## Sobre PageTop - -[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 -configurables, basadas en HTML, CSS y JavaScript. - - -# ⚡️ Guía rápida - -Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`: - -```toml -[dependencies] -pagetop-aliner = "..." -``` - -**Declara la extensión** en tu aplicación (o extensión que la requiera). Recuerda que el orden en -`dependencies()` determina la prioridad relativa frente a las otras extensiones: - -```rust,no_run -use pagetop::prelude::*; - -struct MyApp; - -impl Extension for MyApp { - fn dependencies(&self) -> Vec { - vec![ - // ... - &pagetop_aliner::Aliner, - // ... - ] - } -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&MyApp).run()?.await -} -``` - -Y **selecciona el tema en la configuración** de la aplicación: - -```toml -[app] -theme = "Aliner" -``` - -…o **fuerza el tema por código** en una página concreta: - -```rust,no_run -use pagetop::prelude::*; -use pagetop_aliner::Aliner; - -async fn homepage(request: HttpRequest) -> ResultPage { - Page::new(request) - .with_theme(&Aliner) - .add_child( - Block::new() - .with_title(L10n::l("sample_title")) - .add_child(Html::with(|cx| html! { - p { (L10n::l("sample_content").using(cx)) } - })), - ) - .render() -} -``` - - -# 🚧 Advertencia - -**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su -ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos -hasta que se libere la versión **1.0.0**. - - -# 📜 Licencia - -El código está disponible bajo una doble licencia: - - * **Licencia MIT** - ([LICENSE-MIT](LICENSE-MIT) o también https://opensource.org/licenses/MIT) - - * **Licencia Apache, Versión 2.0** - ([LICENSE-APACHE](LICENSE-APACHE) o también https://www.apache.org/licenses/LICENSE-2.0) - -Puedes elegir la licencia que prefieras. Este enfoque de doble licencia es el estándar de facto en -el ecosistema Rust. diff --git a/extensions/pagetop-aliner/src/lib.rs b/extensions/pagetop-aliner/src/lib.rs deleted file mode 100644 index 4ae4121e..00000000 --- a/extensions/pagetop-aliner/src/lib.rs +++ /dev/null @@ -1,115 +0,0 @@ -/*! -
- -

PageTop Aliner

- -

Tema para PageTop que muestra esquemáticamente la composición de las páginas HTML.

- -[![Doc API](https://img.shields.io/docsrs/pagetop-aliner?label=Doc%20API&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-aliner) -[![Crates.io](https://img.shields.io/crates/v/pagetop-aliner.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop-aliner) -[![Descargas](https://img.shields.io/crates/d/pagetop-aliner.svg?label=Descargas&style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop-aliner) -[![Licencia](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label=Licencia&style=for-the-badge)](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner#licencia) - -
-
- -## Sobre PageTop - -[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 -configurables, basadas en HTML, CSS y JavaScript. - - -# ⚡️ Guía rápida - -Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`: - -```toml -[dependencies] -pagetop-aliner = "..." -``` - -**Declara la extensión** en tu aplicación (o extensión que la requiera). Recuerda que el orden en -`dependencies()` determina la prioridad relativa frente a las otras extensiones: - -```rust,no_run -use pagetop::prelude::*; - -struct MyApp; - -impl Extension for MyApp { - fn dependencies(&self) -> Vec { - vec![ - // ... - &pagetop_aliner::Aliner, - // ... - ] - } -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&MyApp).run()?.await -} -``` - -Y **selecciona el tema en la configuración** de la aplicación: - -```toml -[app] -theme = "Aliner" -``` - -…o **fuerza el tema por código** en una página concreta: - -```rust,no_run -use pagetop::prelude::*; -use pagetop_aliner::Aliner; - -async fn homepage(request: HttpRequest) -> ResultPage { - Page::new(request) - .with_theme(&Aliner) - .add_child( - Block::new() - .with_title(L10n::l("sample_title")) - .add_child(Html::with(|cx| html! { - p { (L10n::l("sample_content").using(cx)) } - })), - ) - .render() -} -``` -*/ - -use pagetop::prelude::*; - -/// Implementa el tema para usar en pruebas que muestran el esquema de páginas HTML. -/// -/// Define un tema mínimo útil para: -/// -/// - Comprobar el funcionamiento de temas, plantillas y regiones. -/// - Verificar integración de componentes y composiciones (*layouts*) sin estilos complejos. -/// - Realizar pruebas de renderizado rápido con salida estable y predecible. -/// - Preparar ejemplos y documentación, sin dependencias visuales (CSS/JS) innecesarias. -pub struct Aliner; - -impl Extension for Aliner { - fn theme(&self) -> Option { - Some(&Self) - } - - fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { - static_files_service!(scfg, [aliner] => "/aliner"); - } -} - -impl Theme for Aliner { - fn after_render_page_body(&self, page: &mut Page) { - page.alter_param("include_basic_assets", true) - .alter_assets(ContextOp::AddStyleSheet( - StyleSheet::from("/aliner/css/styles.css") - .with_version(env!("CARGO_PKG_VERSION")) - .with_weight(-90), - )); - } -} diff --git a/extensions/pagetop-bootsier/.gitattributes b/extensions/pagetop-bootsier/.gitattributes deleted file mode 100644 index 940d6a84..00000000 --- a/extensions/pagetop-bootsier/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -static/** linguist-vendored diff --git a/extensions/pagetop-bootsier/Cargo.toml b/extensions/pagetop-bootsier/Cargo.toml deleted file mode 100644 index 6df6cf69..00000000 --- a/extensions/pagetop-bootsier/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "pagetop-bootsier" -version = "0.0.18" -edition = "2021" - -description = """ - Tema de PageTop basado en Bootstrap para aplicar su catálogo de estilos y componentes flexibles. -""" -categories = ["web-programming", "gui"] -keywords = ["pagetop", "theme", "bootstrap", "css", "js"] - -repository.workspace = true -homepage.workspace = true -license.workspace = true -authors.workspace = true - -[dependencies] -pagetop.workspace = true -serde.workspace = true - -[build-dependencies] -pagetop-build.workspace = true diff --git a/extensions/pagetop-bootsier/LICENSE-APACHE b/extensions/pagetop-bootsier/LICENSE-APACHE deleted file mode 100644 index 263ddac1..00000000 --- a/extensions/pagetop-bootsier/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 Manuel Cillero - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/extensions/pagetop-bootsier/LICENSE-MIT b/extensions/pagetop-bootsier/LICENSE-MIT deleted file mode 100644 index cd8af3d6..00000000 --- a/extensions/pagetop-bootsier/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Manuel Cillero - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/extensions/pagetop-bootsier/README.md b/extensions/pagetop-bootsier/README.md deleted file mode 100644 index d6e1666a..00000000 --- a/extensions/pagetop-bootsier/README.md +++ /dev/null @@ -1,101 +0,0 @@ -
- -

PageTop Bootsier

- -

Tema de PageTop basado en Bootstrap para aplicar su catálogo de estilos y componentes flexibles.

- -[![Doc API](https://img.shields.io/docsrs/pagetop-bootsier?label=Doc%20API&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-bootsier) -[![Crates.io](https://img.shields.io/crates/v/pagetop-bootsier.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop-bootsier) -[![Descargas](https://img.shields.io/crates/d/pagetop-bootsier.svg?label=Descargas&style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop-bootsier) -[![Licencia](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label=Licencia&style=for-the-badge)](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-bootsier#licencia) - -
-
- -## Sobre PageTop - -[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 -configurables, basadas en HTML, CSS y JavaScript. - - -# ⚡️ Guía rápida - -Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`: - -```toml -[dependencies] -pagetop-bootsier = "..." -``` - -**Declara la extensión** en tu aplicación (o extensión que la requiera). Recuerda que el orden en -`dependencies()` determina la prioridad relativa frente a las otras extensiones: - -```rust,no_run -use pagetop::prelude::*; - -struct MyApp; - -impl Extension for MyApp { - fn dependencies(&self) -> Vec { - vec![ - // ... - &pagetop_bootsier::Bootsier, - // ... - ] - } -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&MyApp).run()?.await -} -``` - -Y **selecciona el tema en la configuración** de la aplicación: - -```toml -[app] -theme = "Bootsier" -``` - -…o **fuerza el tema por código** en una página concreta: - -```rust,no_run -use pagetop::prelude::*; -use pagetop_bootsier::Bootsier; - -async fn homepage(request: HttpRequest) -> ResultPage { - Page::new(request) - .with_theme(&Bootsier) - .add_child( - Block::new() - .with_title(L10n::l("sample_title")) - .add_child(Html::with(|cx| html! { - p { (L10n::l("sample_content").using(cx)) } - })), - ) - .render() -} -``` - - -# 🚧 Advertencia - -**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su -ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos -hasta que se libere la versión **1.0.0**. - - -# 📜 Licencia - -El código está disponible bajo una doble licencia: - - * **Licencia MIT** - ([LICENSE-MIT](LICENSE-MIT) o también https://opensource.org/licenses/MIT) - - * **Licencia Apache, Versión 2.0** - ([LICENSE-APACHE](LICENSE-APACHE) o también https://www.apache.org/licenses/LICENSE-2.0) - -Puedes elegir la licencia que prefieras. Este enfoque de doble licencia es el estándar de facto en -el ecosistema Rust. diff --git a/extensions/pagetop-bootsier/build.rs b/extensions/pagetop-bootsier/build.rs deleted file mode 100644 index df7a2750..00000000 --- a/extensions/pagetop-bootsier/build.rs +++ /dev/null @@ -1,20 +0,0 @@ -use pagetop_build::StaticFilesBundle; - -use std::env; -use std::path::Path; - -fn main() -> std::io::Result<()> { - StaticFilesBundle::from_scss("./static/scss/bootsier.scss", "bootstrap.min.css") - .with_name("bootsier_bs") - .build()?; - StaticFilesBundle::from_dir("./static/js", Some(bootstrap_js_files)) - .with_name("bootsier_js") - .build() -} - -fn bootstrap_js_files(path: &Path) -> bool { - let bootstrap_js = "bootstrap.bundle.min.js"; - // No filtra durante el desarrollo, solo en la compilación "release". - env::var("PROFILE").unwrap_or_else(|_| "release".to_string()) != "release" - || path.file_name().is_some_and(|f| f == bootstrap_js) -} diff --git a/extensions/pagetop-bootsier/src/config.rs b/extensions/pagetop-bootsier/src/config.rs deleted file mode 100644 index 6c2365ba..00000000 --- a/extensions/pagetop-bootsier/src/config.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Opciones de configuración del tema. -//! -//! Ejemplo: -//! -//! ```toml -//! [bootsier] -//! max_width = "90rem" -//! ``` -//! -//! Uso: -//! -//! ```rust -//! # use pagetop::prelude::*; -//! use pagetop_bootsier::config; -//! -//! assert_eq!(config::SETTINGS.bootsier.max_width, UnitValue::Px(1440)); -//! ``` -//! -//! Consulta [`pagetop::config`] para ver cómo PageTop lee los archivos de configuración y aplica -//! los valores a los ajustes. - -use pagetop::prelude::*; - -use serde::Deserialize; - -include_config!(SETTINGS: Settings => [ - // [bootsier] - "bootsier.max_width" => "1440px", -]); - -#[derive(Debug, Deserialize)] -/// Tipos para la sección [`[bootsier]`](Bootsier) de [`SETTINGS`]. -pub struct Settings { - pub bootsier: Bootsier, -} -#[derive(Debug, Deserialize)] -/// Sección `[bootsier]` de la configuración. Forma parte de [`Settings`]. -pub struct Bootsier { - /// Ancho máximo predeterminado para la página, por ejemplo "100%" o "90rem". - pub max_width: UnitValue, -} diff --git a/extensions/pagetop-bootsier/src/lib.rs b/extensions/pagetop-bootsier/src/lib.rs deleted file mode 100644 index 0bf94f47..00000000 --- a/extensions/pagetop-bootsier/src/lib.rs +++ /dev/null @@ -1,132 +0,0 @@ -/*! -
- -

PageTop Bootsier

- -

Tema de PageTop basado en Bootstrap para aplicar su catálogo de estilos y componentes flexibles.

- -[![Doc API](https://img.shields.io/docsrs/pagetop-bootsier?label=Doc%20API&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-bootsier) -[![Crates.io](https://img.shields.io/crates/v/pagetop-bootsier.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop-bootsier) -[![Descargas](https://img.shields.io/crates/d/pagetop-bootsier.svg?label=Descargas&style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop-bootsier) -[![Licencia](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label=Licencia&style=for-the-badge)](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-bootsier#licencia) - -
-
- -## Sobre PageTop - -[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 -configurables, basadas en HTML, CSS y JavaScript. - - -# ⚡️ Guía rápida - -Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`: - -```toml -[dependencies] -pagetop-bootsier = "..." -``` - -**Declara la extensión** en tu aplicación (o extensión que la requiera). Recuerda que el orden en -`dependencies()` determina la prioridad relativa frente a las otras extensiones: - -```rust,no_run -use pagetop::prelude::*; - -struct MyApp; - -impl Extension for MyApp { - fn dependencies(&self) -> Vec { - vec![ - // ... - &pagetop_bootsier::Bootsier, - // ... - ] - } -} - -#[pagetop::main] -async fn main() -> std::io::Result<()> { - Application::prepare(&MyApp).run()?.await -} -``` - -Y **selecciona el tema en la configuración** de la aplicación: - -```toml -[app] -theme = "Bootsier" -``` - -…o **fuerza el tema por código** en una página concreta: - -```rust,no_run -use pagetop::prelude::*; -use pagetop_bootsier::Bootsier; - -async fn homepage(request: HttpRequest) -> ResultPage { - Page::new(request) - .with_theme(&Bootsier) - .add_child( - Block::new() - .with_title(L10n::l("sample_title")) - .add_child(Html::with(|cx| html! { - p { (L10n::l("sample_content").using(cx)) } - })), - ) - .render() -} -``` -*/ - -#![doc( - html_favicon_url = "https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/static/favicon.ico" -)] - -use pagetop::prelude::*; - -include_locales!(LOCALES_BOOTSIER); - -// Versión de la librería Bootstrap. -const BOOTSTRAP_VERSION: &str = "5.3.8"; - -pub mod config; - -pub mod theme; - -/// *Prelude* del tema. -pub mod prelude { - pub use crate::config::*; - pub use crate::theme::*; -} - -/// Implementa el tema. -pub struct Bootsier; - -impl Extension for Bootsier { - fn theme(&self) -> Option { - Some(&Self) - } - - fn configure_service(&self, scfg: &mut service::web::ServiceConfig) { - static_files_service!(scfg, [bootsier_bs] => "/bootsier/bs"); - static_files_service!(scfg, [bootsier_js] => "/bootsier/js"); - } -} - -impl Theme for Bootsier { - fn after_render_page_body(&self, page: &mut Page) { - page.alter_assets(ContextOp::AddStyleSheet( - StyleSheet::from("/bootsier/bs/bootstrap.min.css") - .with_version(BOOTSTRAP_VERSION) - .with_weight(-90), - )) - .alter_assets(ContextOp::AddJavaScript( - JavaScript::defer("/bootsier/js/bootstrap.bundle.min.js") - .with_version(BOOTSTRAP_VERSION) - .with_weight(-90), - )); - } -} diff --git a/extensions/pagetop-bootsier/src/locale/en-US/components.ftl b/extensions/pagetop-bootsier/src/locale/en-US/components.ftl deleted file mode 100644 index e3b0d6e6..00000000 --- a/extensions/pagetop-bootsier/src/locale/en-US/components.ftl +++ /dev/null @@ -1,8 +0,0 @@ -# Dropdown -dropdown_toggle = Toggle Dropdown - -# Offcanvas -offcanvas_close = Close - -# Navbar -toggle = Toggle navigation diff --git a/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl b/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl deleted file mode 100644 index ab7ff687..00000000 --- a/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl +++ /dev/null @@ -1,8 +0,0 @@ -# Dropdown -dropdown_toggle = Mostrar/ocultar menú - -# Offcanvas -offcanvas_close = Cerrar - -# Navbar -toggle = Mostrar/ocultar navegación diff --git a/extensions/pagetop-bootsier/src/theme.rs b/extensions/pagetop-bootsier/src/theme.rs deleted file mode 100644 index 2c6b5757..00000000 --- a/extensions/pagetop-bootsier/src/theme.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Definiciones y componentes del tema. -//! -//! En esta página, el apartado **Modules** incluye las definiciones necesarias para los componentes -//! que se muestran en el apartado **Structs**, mientras que en **Enums** se listan los elementos -//! auxiliares del tema utilizados en clases y componentes. - -mod aux; -pub use aux::*; - -pub mod classes; - -// Container. -pub mod container; -#[doc(inline)] -pub use container::Container; - -// Dropdown. -pub mod dropdown; -#[doc(inline)] -pub use dropdown::Dropdown; - -// Image. -pub mod image; -#[doc(inline)] -pub use image::Image; - -// Nav. -pub mod nav; -#[doc(inline)] -pub use nav::Nav; - -// Navbar. -pub mod navbar; -#[doc(inline)] -pub use navbar::Navbar; - -// Offcanvas. -pub mod offcanvas; -#[doc(inline)] -pub use offcanvas::Offcanvas; diff --git a/extensions/pagetop-bootsier/src/theme/aux.rs b/extensions/pagetop-bootsier/src/theme/aux.rs deleted file mode 100644 index 99431fe3..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Colección de elementos auxiliares de Bootstrap para Bootsier. - -mod breakpoint; -pub use breakpoint::BreakPoint; - -mod color; -pub use color::{Color, Opacity}; -pub use color::{ColorBg, ColorText}; - -mod layout; -pub use layout::{ScaleSize, Side}; - -mod border; -pub use border::BorderColor; - -mod rounded; -pub use rounded::RoundedRadius; - -mod button; -pub use button::{ButtonColor, ButtonSize}; diff --git a/extensions/pagetop-bootsier/src/theme/aux/border.rs b/extensions/pagetop-bootsier/src/theme/aux/border.rs deleted file mode 100644 index 43882767..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux/border.rs +++ /dev/null @@ -1,87 +0,0 @@ -use pagetop::prelude::*; - -use crate::theme::aux::Color; - -/// Colores `border-*` para los bordes ([`classes::Border`](crate::theme::classes::Border)). -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum BorderColor { - /// No define ninguna clase. - #[default] - Default, - /// Genera internamente clases `border-{color}`. - Theme(Color), - /// Genera internamente clases `border-{color}-subtle` (un tono suavizado del color). - Subtle(Color), - /// Color negro. - Black, - /// Color blanco. - White, -} - -impl BorderColor { - const BORDER: &str = "border"; - const BORDER_PREFIX: &str = "border-"; - - // Devuelve el sufijo de la clase `border-*`, o `None` si no define ninguna clase. - #[rustfmt::skip] - #[inline] - const fn suffix(self) -> Option<&'static str> { - match self { - Self::Default => None, - Self::Theme(_) => Some(""), - Self::Subtle(_) => Some("-subtle"), - Self::Black => Some("-black"), - Self::White => Some("-white"), - } - } - - // Añade la clase `border-*` a la cadena de clases. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - if let Some(suffix) = self.suffix() { - if !classes.is_empty() { - classes.push(' '); - } - match self { - Self::Theme(c) | Self::Subtle(c) => { - classes.push_str(Self::BORDER_PREFIX); - classes.push_str(c.as_str()); - } - _ => classes.push_str(Self::BORDER), - } - classes.push_str(suffix); - } - } - - /// Devuelve la clase `border-*` correspondiente al color de borde. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(BorderColor::Theme(Color::Primary).to_class(), "border-primary"); - /// assert_eq!(BorderColor::Subtle(Color::Warning).to_class(), "border-warning-subtle"); - /// assert_eq!(BorderColor::Black.to_class(), "border-black"); - /// assert_eq!(BorderColor::Default.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - if let Some(suffix) = self.suffix() { - let base_len = match self { - Self::Theme(c) | Self::Subtle(c) => Self::BORDER_PREFIX.len() + c.as_str().len(), - _ => Self::BORDER.len(), - }; - let mut class = String::with_capacity(base_len + suffix.len()); - match self { - Self::Theme(c) | Self::Subtle(c) => { - class.push_str(Self::BORDER_PREFIX); - class.push_str(c.as_str()); - } - _ => class.push_str(Self::BORDER), - } - class.push_str(suffix); - return class; - } - String::new() - } -} diff --git a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs deleted file mode 100644 index 4d9a7626..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs +++ /dev/null @@ -1,114 +0,0 @@ -use pagetop::prelude::*; - -/// Define los puntos de ruptura (*breakpoints*) para aplicar diseño *responsive*. -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum BreakPoint { - /// **Menos de 576px**. Dispositivos muy pequeños: teléfonos en modo vertical. - #[default] - None, - /// **576px o más** - Dispositivos pequeños: teléfonos en modo horizontal. - SM, - /// **768px o más** - Dispositivos medianos: tabletas. - MD, - /// **992px o más** - Dispositivos grandes: puestos de escritorio. - LG, - /// **1200px o más** - Dispositivos muy grandes: puestos de escritorio grandes. - XL, - /// **1400px o más** - Dispositivos extragrandes: puestos de escritorio más grandes. - XXL, -} - -impl BreakPoint { - // Devuelve la identificación del punto de ruptura. - #[rustfmt::skip] - #[inline] - pub(crate) const fn as_str(self) -> &'static str { - match self { - Self::None => "", - Self::SM => "sm", - Self::MD => "md", - Self::LG => "lg", - Self::XL => "xl", - Self::XXL => "xxl", - } - } - - // Añade el punto de ruptura con un prefijo y un sufijo (opcional) separados por un guion `-` a - // la cadena de clases. - // - // - Para `None` - `prefix` o `prefix-suffix` (si `suffix` no está vacío). - // - Para `SM..XXL` - `prefix-{breakpoint}` o `prefix-{breakpoint}-{suffix}`. - #[inline] - pub(crate) fn push_class(self, classes: &mut String, prefix: &str, suffix: &str) { - if prefix.is_empty() { - return; - } - if !classes.is_empty() { - classes.push(' '); - } - match self { - Self::None => classes.push_str(prefix), - _ => { - classes.push_str(prefix); - classes.push('-'); - classes.push_str(self.as_str()); - } - } - if !suffix.is_empty() { - classes.push('-'); - classes.push_str(suffix); - } - } - - // Devuelve la clase para el punto de ruptura, con un prefijo y un sufijo opcional, separados - // por un guion `-`. - // - // - Para `None` - `prefix` o `prefix-suffix` (si `suffix` no está vacío). - // - Para `SM..XXL` - `prefix-{breakpoint}` o `prefix-{breakpoint}-{suffix}`. - // - Si `prefix` está vacío devuelve `""`. - // - // # Ejemplos - // - // ```rust - // # use pagetop_bootsier::prelude::*; - // let bp = BreakPoint::MD; - // assert_eq!(bp.class_with("col", ""), "col-md"); - // assert_eq!(bp.class_with("col", "6"), "col-md-6"); - // - // let bp = BreakPoint::None; - // assert_eq!(bp.class_with("offcanvas", ""), "offcanvas"); - // assert_eq!(bp.class_with("col", "12"), "col-12"); - // - // let bp = BreakPoint::LG; - // assert_eq!(bp.class_with("", "3"), ""); - // ``` - #[inline] - pub(crate) fn class_with(self, prefix: &str, suffix: &str) -> String { - if prefix.is_empty() { - return String::new(); - } - - let bp = self.as_str(); - let has_bp = !bp.is_empty(); - let has_suffix = !suffix.is_empty(); - - let mut len = prefix.len(); - if has_bp { - len += 1 + bp.len(); - } - if has_suffix { - len += 1 + suffix.len(); - } - let mut class = String::with_capacity(len); - class.push_str(prefix); - if has_bp { - class.push('-'); - class.push_str(bp); - } - if has_suffix { - class.push('-'); - class.push_str(suffix); - } - class - } -} diff --git a/extensions/pagetop-bootsier/src/theme/aux/button.rs b/extensions/pagetop-bootsier/src/theme/aux/button.rs deleted file mode 100644 index 0d1df87d..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux/button.rs +++ /dev/null @@ -1,143 +0,0 @@ -use pagetop::prelude::*; - -use crate::theme::aux::Color; - -// **< ButtonColor >******************************************************************************** - -/// Variantes de color `btn-*` para botones. -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum ButtonColor { - /// No define ninguna clase. - #[default] - Default, - /// Genera internamente clases `btn-{color}` (botón relleno). - Background(Color), - /// Genera `btn-outline-{color}` (fondo transparente y contorno con borde). - Outline(Color), - /// Aplica estilo de los enlaces (`btn-link`), sin caja ni fondo, heredando el color de texto. - Link, -} - -impl ButtonColor { - const BTN_PREFIX: &str = "btn-"; - const BTN_OUTLINE_PREFIX: &str = "btn-outline-"; - const BTN_LINK: &str = "btn-link"; - - // Añade la clase `btn-*` a la cadena de clases. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - if let Self::Default = self { - return; - } - if !classes.is_empty() { - classes.push(' '); - } - match self { - Self::Default => unreachable!(), - Self::Background(c) => { - classes.push_str(Self::BTN_PREFIX); - classes.push_str(c.as_str()); - } - Self::Outline(c) => { - classes.push_str(Self::BTN_OUTLINE_PREFIX); - classes.push_str(c.as_str()); - } - Self::Link => { - classes.push_str(Self::BTN_LINK); - } - } - } - - /// Devuelve la clase `btn-*` correspondiente al color del botón. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!( - /// ButtonColor::Background(Color::Primary).to_class(), - /// "btn-primary" - /// ); - /// assert_eq!( - /// ButtonColor::Outline(Color::Danger).to_class(), - /// "btn-outline-danger" - /// ); - /// assert_eq!(ButtonColor::Link.to_class(), "btn-link"); - /// assert_eq!(ButtonColor::Default.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - match self { - Self::Default => String::new(), - Self::Background(c) => { - let color = c.as_str(); - let mut class = String::with_capacity(Self::BTN_PREFIX.len() + color.len()); - class.push_str(Self::BTN_PREFIX); - class.push_str(color); - class - } - Self::Outline(c) => { - let color = c.as_str(); - let mut class = String::with_capacity(Self::BTN_OUTLINE_PREFIX.len() + color.len()); - class.push_str(Self::BTN_OUTLINE_PREFIX); - class.push_str(color); - class - } - Self::Link => Self::BTN_LINK.to_string(), - } - } -} - -// **< ButtonSize >********************************************************************************* - -/// Tamaño visual de un botón. -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum ButtonSize { - /// Tamaño por defecto del tema (no añade clase). - #[default] - Default, - /// Botón compacto. - Small, - /// Botón destacado/grande. - Large, -} - -impl ButtonSize { - const BTN_SM: &str = "btn-sm"; - const BTN_LG: &str = "btn-lg"; - - // Añade la clase de tamaño `btn-sm` o `btn-lg` a la cadena de clases. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - if let Self::Default = self { - return; - } - if !classes.is_empty() { - classes.push(' '); - } - match self { - Self::Default => unreachable!(), - Self::Small => classes.push_str(Self::BTN_SM), - Self::Large => classes.push_str(Self::BTN_LG), - } - } - - /// Devuelve la clase `btn-sm` o `btn-lg` correspondiente al tamaño del botón. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(ButtonSize::Small.to_class(), "btn-sm"); - /// assert_eq!(ButtonSize::Large.to_class(), "btn-lg"); - /// assert_eq!(ButtonSize::Default.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - match self { - Self::Default => String::new(), - Self::Small => Self::BTN_SM.to_string(), - Self::Large => Self::BTN_LG.to_string(), - } - } -} diff --git a/extensions/pagetop-bootsier/src/theme/aux/color.rs b/extensions/pagetop-bootsier/src/theme/aux/color.rs deleted file mode 100644 index 480ff3d8..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux/color.rs +++ /dev/null @@ -1,375 +0,0 @@ -use pagetop::prelude::*; - -// **< Color >************************************************************************************** - -/// Paleta de colores temáticos. -/// -/// Equivalen a los nombres estándar definidos por Bootstrap (`primary`, `secondary`, `success`, -/// etc.). Este tipo enumerado sirve de base para componer las clases de color para fondo -/// ([`classes::Background`](crate::theme::classes::Background)), bordes -/// ([`classes::Border`](crate::theme::classes::Border)) y texto -/// ([`classes::Text`](crate::theme::classes::Text)). -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum Color { - #[default] - Primary, - Secondary, - Success, - Info, - Warning, - Danger, - Light, - Dark, -} - -impl Color { - // Devuelve el nombre del color. - #[rustfmt::skip] - #[inline] - pub(crate) const fn as_str(self) -> &'static str { - match self { - Self::Primary => "primary", - Self::Secondary => "secondary", - Self::Success => "success", - Self::Info => "info", - Self::Warning => "warning", - Self::Danger => "danger", - Self::Light => "light", - Self::Dark => "dark", - } - } - - /* Añade el nombre del color a la cadena de clases (reservado). - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - if !classes.is_empty() { - classes.push(' '); - } - classes.push_str(self.as_str()); - } */ - - /// Devuelve la clase correspondiente al color. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(Color::Primary.to_class(), "primary"); - /// assert_eq!(Color::Danger.to_class(), "danger"); - /// ``` - #[inline] - pub fn to_class(self) -> String { - self.as_str().to_owned() - } -} - -// **< Opacity >************************************************************************************ - -/// Niveles de opacidad (`opacity-*`). -/// -/// Se usa normalmente para graduar la transparencia del color de fondo `bg-opacity-*` -/// ([`classes::Background`](crate::theme::classes::Background)), de los bordes `border-opacity-*` -/// ([`classes::Border`](crate::theme::classes::Border)) o del texto `text-opacity-*` -/// ([`classes::Text`](crate::theme::classes::Text)). -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum Opacity { - /// No define ninguna clase. - #[default] - Default, - /// Permite generar clases `*-opacity-100` (100% de opacidad). - Opaque, - /// Permite generar clases `*-opacity-75` (75%). - SemiOpaque, - /// Permite generar clases `*-opacity-50` (50%). - Half, - /// Permite generar clases `*-opacity-25` (25%). - SemiTransparent, - /// Permite generar clases `*-opacity-10` (10%). - AlmostTransparent, - /// Permite generar clases `*-opacity-0` (0%, totalmente transparente). - Transparent, -} - -impl Opacity { - const OPACITY: &str = "opacity"; - const OPACITY_PREFIX: &str = "-opacity"; - - // Devuelve el sufijo para `*opacity-*`, o `None` si no define ninguna clase. - #[rustfmt::skip] - #[inline] - const fn suffix(self) -> Option<&'static str> { - match self { - Self::Default => None, - Self::Opaque => Some("-100"), - Self::SemiOpaque => Some("-75"), - Self::Half => Some("-50"), - Self::SemiTransparent => Some("-25"), - Self::AlmostTransparent => Some("-10"), - Self::Transparent => Some("-0"), - } - } - - // Añade la opacidad a la cadena de clases usando el prefijo dado (`bg`, `border`, `text`, o - // vacío para `opacity-*`). - #[inline] - pub(crate) fn push_class(self, classes: &mut String, prefix: &str) { - if let Some(suffix) = self.suffix() { - if !classes.is_empty() { - classes.push(' '); - } - if prefix.is_empty() { - classes.push_str(Self::OPACITY); - } else { - classes.push_str(prefix); - classes.push_str(Self::OPACITY_PREFIX); - } - classes.push_str(suffix); - } - } - - // Devuelve la clase de opacidad con el prefijo dado (`bg`, `border`, `text`, o vacío para - // `opacity-*`). - // - // # Ejemplos - // - // ```rust - // # use pagetop_bootsier::prelude::*; - // assert_eq!(Opacity::Opaque.class_with(""), "opacity-100"); - // assert_eq!(Opacity::Half.class_with("bg"), "bg-opacity-50"); - // assert_eq!(Opacity::SemiTransparent.class_with("text"), "text-opacity-25"); - // assert_eq!(Opacity::Default.class_with("bg"), ""); - // ``` - #[inline] - pub(crate) fn class_with(self, prefix: &str) -> String { - if let Some(suffix) = self.suffix() { - let base_len = if prefix.is_empty() { - Self::OPACITY.len() - } else { - prefix.len() + Self::OPACITY_PREFIX.len() - }; - let mut class = String::with_capacity(base_len + suffix.len()); - if prefix.is_empty() { - class.push_str(Self::OPACITY); - } else { - class.push_str(prefix); - class.push_str(Self::OPACITY_PREFIX); - } - class.push_str(suffix); - return class; - } - String::new() - } - - /// Devuelve la clase de opacidad `opacity-*`. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(Opacity::Opaque.to_class(), "opacity-100"); - /// assert_eq!(Opacity::Half.to_class(), "opacity-50"); - /// assert_eq!(Opacity::Default.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - self.class_with("") - } -} - -// **< ColorBg >************************************************************************************ - -/// Colores `bg-*` para el fondo. -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum ColorBg { - /// No define ninguna clase. - #[default] - Default, - /// Fondo predefinido del tema (`bg-body`). - Body, - /// Fondo predefinido del tema (`bg-body-secondary`). - BodySecondary, - /// Fondo predefinido del tema (`bg-body-tertiary`). - BodyTertiary, - /// Genera internamente clases `bg-{color}` (p. ej., `bg-primary`). - Theme(Color), - /// Genera internamente clases `bg-{color}-subtle` (un tono suavizado del color). - Subtle(Color), - /// Color negro. - Black, - /// Color blanco. - White, - /// No aplica ningún color de fondo (`bg-transparent`). - Transparent, -} - -impl ColorBg { - const BG: &str = "bg"; - const BG_PREFIX: &str = "bg-"; - - // Devuelve el sufijo de la clase `bg-*`, o `None` si no define ninguna clase. - #[rustfmt::skip] - #[inline] - const fn suffix(self) -> Option<&'static str> { - match self { - Self::Default => None, - Self::Body => Some("-body"), - Self::BodySecondary => Some("-body-secondary"), - Self::BodyTertiary => Some("-body-tertiary"), - Self::Theme(_) => Some(""), - Self::Subtle(_) => Some("-subtle"), - Self::Black => Some("-black"), - Self::White => Some("-white"), - Self::Transparent => Some("-transparent"), - } - } - - // Añade la clase de fondo `bg-*` a la cadena de clases. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - if let Some(suffix) = self.suffix() { - if !classes.is_empty() { - classes.push(' '); - } - match self { - Self::Theme(c) | Self::Subtle(c) => { - classes.push_str(Self::BG_PREFIX); - classes.push_str(c.as_str()); - } - _ => classes.push_str(Self::BG), - } - classes.push_str(suffix); - } - } - - /// Devuelve la clase `bg-*` correspondiente al fondo. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(ColorBg::Body.to_class(), "bg-body"); - /// assert_eq!(ColorBg::Theme(Color::Primary).to_class(), "bg-primary"); - /// assert_eq!(ColorBg::Subtle(Color::Warning).to_class(), "bg-warning-subtle"); - /// assert_eq!(ColorBg::Transparent.to_class(), "bg-transparent"); - /// assert_eq!(ColorBg::Default.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - if let Some(suffix) = self.suffix() { - let base_len = match self { - Self::Theme(c) | Self::Subtle(c) => Self::BG_PREFIX.len() + c.as_str().len(), - _ => Self::BG.len(), - }; - let mut class = String::with_capacity(base_len + suffix.len()); - match self { - Self::Theme(c) | Self::Subtle(c) => { - class.push_str(Self::BG_PREFIX); - class.push_str(c.as_str()); - } - _ => class.push_str(Self::BG), - } - class.push_str(suffix); - return class; - } - String::new() - } -} - -// **< ColorText >********************************************************************************** - -/// Colores `text-*` para el texto. -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum ColorText { - /// No define ninguna clase. - #[default] - Default, - /// Color predefinido del tema (`text-body`). - Body, - /// Color predefinido del tema (`text-body-emphasis`). - BodyEmphasis, - /// Color predefinido del tema (`text-body-secondary`). - BodySecondary, - /// Color predefinido del tema (`text-body-tertiary`). - BodyTertiary, - /// Genera internamente clases `text-{color}`. - Theme(Color), - /// Genera internamente clases `text-{color}-emphasis` (mayor contraste acorde al tema). - Emphasis(Color), - /// Color negro. - Black, - /// Color blanco. - White, -} - -impl ColorText { - const TEXT: &str = "text"; - const TEXT_PREFIX: &str = "text-"; - - // Devuelve el sufijo de la clase `text-*`, o `None` si no define ninguna clase. - #[rustfmt::skip] - #[inline] - const fn suffix(self) -> Option<&'static str> { - match self { - Self::Default => None, - Self::Body => Some("-body"), - Self::BodyEmphasis => Some("-body-emphasis"), - Self::BodySecondary => Some("-body-secondary"), - Self::BodyTertiary => Some("-body-tertiary"), - Self::Theme(_) => Some(""), - Self::Emphasis(_) => Some("-emphasis"), - Self::Black => Some("-black"), - Self::White => Some("-white"), - } - } - - // Añade la clase de texto `text-*` a la cadena de clases. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - if let Some(suffix) = self.suffix() { - if !classes.is_empty() { - classes.push(' '); - } - match self { - Self::Theme(c) | Self::Emphasis(c) => { - classes.push_str(Self::TEXT_PREFIX); - classes.push_str(c.as_str()); - } - _ => classes.push_str(Self::TEXT), - } - classes.push_str(suffix); - } - } - - /// Devuelve la clase `text-*` correspondiente al color del texto. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(ColorText::Body.to_class(), "text-body"); - /// assert_eq!(ColorText::Theme(Color::Primary).to_class(), "text-primary"); - /// assert_eq!(ColorText::Emphasis(Color::Danger).to_class(), "text-danger-emphasis"); - /// assert_eq!(ColorText::Black.to_class(), "text-black"); - /// assert_eq!(ColorText::Default.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - if let Some(suffix) = self.suffix() { - let base_len = match self { - Self::Theme(c) | Self::Emphasis(c) => Self::TEXT_PREFIX.len() + c.as_str().len(), - _ => Self::TEXT.len(), - }; - let mut class = String::with_capacity(base_len + suffix.len()); - match self { - Self::Theme(c) | Self::Emphasis(c) => { - class.push_str(Self::TEXT_PREFIX); - class.push_str(c.as_str()); - } - _ => class.push_str(Self::TEXT), - } - class.push_str(suffix); - return class; - } - String::new() - } -} diff --git a/extensions/pagetop-bootsier/src/theme/aux/layout.rs b/extensions/pagetop-bootsier/src/theme/aux/layout.rs deleted file mode 100644 index 1d351582..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux/layout.rs +++ /dev/null @@ -1,104 +0,0 @@ -use pagetop::prelude::*; - -// **< ScaleSize >********************************************************************************** - -/// Escala discreta de tamaños para definir clases utilitarias. -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum ScaleSize { - /// Sin tamaño (no define ninguna clase). - #[default] - None, - /// Tamaño automático. - Auto, - /// Escala cero. - Zero, - /// Escala uno. - One, - /// Escala dos. - Two, - /// Escala tres. - Three, - /// Escala cuatro. - Four, - /// Escala cinco. - Five, -} - -impl ScaleSize { - // Devuelve el sufijo para el tamaño (`"-0"`, `"-1"`, etc.), o `None` si no define ninguna - // clase, o `""` para el tamaño automático. - #[rustfmt::skip] - #[inline] - const fn suffix(self) -> Option<&'static str> { - match self { - Self::None => None, - Self::Auto => Some(""), - Self::Zero => Some("-0"), - Self::One => Some("-1"), - Self::Two => Some("-2"), - Self::Three => Some("-3"), - Self::Four => Some("-4"), - Self::Five => Some("-5"), - } - } - - // Añade el tamaño a la cadena de clases usando el prefijo dado. - #[inline] - pub(crate) fn push_class(self, classes: &mut String, prefix: &str) { - if !prefix.is_empty() { - if let Some(suffix) = self.suffix() { - if !classes.is_empty() { - classes.push(' '); - } - classes.push_str(prefix); - classes.push_str(suffix); - } - } - } - - /* Devuelve la clase del tamaño para el prefijo, o una cadena vacía si no aplica (reservado). - // - // # Ejemplo - // - // ```rust - // # use pagetop_bootsier::prelude::*; - // assert_eq!(ScaleSize::Auto.class_with("border"), "border"); - // assert_eq!(ScaleSize::Zero.class_with("m"), "m-0"); - // assert_eq!(ScaleSize::Three.class_with("p"), "p-3"); - // assert_eq!(ScaleSize::None.class_with("border"), ""); - // ``` - #[inline] - pub(crate) fn class_with(self, prefix: &str) -> String { - if !prefix.is_empty() { - if let Some(suffix) = self.suffix() { - let mut class = String::with_capacity(prefix.len() + suffix.len()); - class.push_str(prefix); - class.push_str(suffix); - return class; - } - } - String::new() - } */ -} - -// **< Side >*************************************************************************************** - -/// Lados sobre los que aplicar una clase utilitaria (respetando LTR/RTL). -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum Side { - /// Todos los lados. - #[default] - All, - /// Lado superior. - Top, - /// Lado inferior. - Bottom, - /// Lado lógico de inicio (respetando RTL). - Start, - /// Lado lógico de fin (respetando RTL). - End, - /// Lados lógicos laterales (abreviatura *x*). - LeftAndRight, - /// Lados superior e inferior (abreviatura *y*). - TopAndBottom, -} diff --git a/extensions/pagetop-bootsier/src/theme/aux/rounded.rs b/extensions/pagetop-bootsier/src/theme/aux/rounded.rs deleted file mode 100644 index 20e061d6..00000000 --- a/extensions/pagetop-bootsier/src/theme/aux/rounded.rs +++ /dev/null @@ -1,117 +0,0 @@ -use pagetop::prelude::*; - -/// Radio para el redondeo de esquinas ([`classes::Rounded`](crate::theme::classes::Rounded)). -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub enum RoundedRadius { - /// No define ninguna clase. - #[default] - None, - /// Genera `rounded` (radio por defecto del tema). - Default, - /// Genera `rounded-0` (sin redondeo). - Zero, - /// Genera `rounded-1`. - Scale1, - /// Genera `rounded-2`. - Scale2, - /// Genera `rounded-3`. - Scale3, - /// Genera `rounded-4`. - Scale4, - /// Genera `rounded-5`. - Scale5, - /// Genera `rounded-circle`. - Circle, - /// Genera `rounded-pill`. - Pill, -} - -impl RoundedRadius { - const ROUNDED: &str = "rounded"; - - // Devuelve el sufijo para `*rounded-*`, o `None` si no define ninguna clase, o `""` para el - // redondeo por defecto. - #[rustfmt::skip] - #[inline] - const fn suffix(self) -> Option<&'static str> { - match self { - Self::None => None, - Self::Default => Some(""), - Self::Zero => Some("-0"), - Self::Scale1 => Some("-1"), - Self::Scale2 => Some("-2"), - Self::Scale3 => Some("-3"), - Self::Scale4 => Some("-4"), - Self::Scale5 => Some("-5"), - Self::Circle => Some("-circle"), - Self::Pill => Some("-pill"), - } - } - - // Añade el redondeo de esquinas a la cadena de clases usando el prefijo dado (`rounded-top`, - // `rounded-bottom-start`, o vacío para `rounded-*`). - #[inline] - pub(crate) fn push_class(self, classes: &mut String, prefix: &str) { - if let Some(suffix) = self.suffix() { - if !classes.is_empty() { - classes.push(' '); - } - if prefix.is_empty() { - classes.push_str(Self::ROUNDED); - } else { - classes.push_str(prefix); - } - classes.push_str(suffix); - } - } - - // Devuelve la clase para el redondeo de esquinas con el prefijo dado (`rounded-top`, - // `rounded-bottom-start`, o vacío para `rounded-*`). - // - // # Ejemplos - // - // ```rust - // # use pagetop_bootsier::prelude::*; - // assert_eq!(RoundedRadius::Scale2.class_with(""), "rounded-2"); - // assert_eq!(RoundedRadius::Zero.class_with("rounded-top"), "rounded-top-0"); - // assert_eq!(RoundedRadius::Scale3.class_with("rounded-top-end"), "rounded-top-end-3"); - // assert_eq!(RoundedRadius::Circle.class_with(""), "rounded-circle"); - // assert_eq!(RoundedRadius::None.class_with("rounded-bottom-start"), ""); - // ``` - #[inline] - pub(crate) fn class_with(self, prefix: &str) -> String { - if let Some(suffix) = self.suffix() { - let base_len = if prefix.is_empty() { - Self::ROUNDED.len() - } else { - prefix.len() - }; - let mut class = String::with_capacity(base_len + suffix.len()); - if prefix.is_empty() { - class.push_str(Self::ROUNDED); - } else { - class.push_str(prefix); - } - class.push_str(suffix); - return class; - } - String::new() - } - - /// Devuelve la clase `rounded-*` para el redondeo de esquinas. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(RoundedRadius::Default.to_class(), "rounded"); - /// assert_eq!(RoundedRadius::Zero.to_class(), "rounded-0"); - /// assert_eq!(RoundedRadius::Scale3.to_class(), "rounded-3"); - /// assert_eq!(RoundedRadius::Circle.to_class(), "rounded-circle"); - /// assert_eq!(RoundedRadius::None.to_class(), ""); - /// ``` - #[inline] - pub fn to_class(self) -> String { - self.class_with("") - } -} diff --git a/extensions/pagetop-bootsier/src/theme/classes.rs b/extensions/pagetop-bootsier/src/theme/classes.rs deleted file mode 100644 index 9e6c234d..00000000 --- a/extensions/pagetop-bootsier/src/theme/classes.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Conjunto de clases para aplicar en componentes del tema. - -mod color; -pub use color::{Background, Text}; - -mod border; -pub use border::Border; - -mod rounded; -pub use rounded::Rounded; - -mod layout; -pub use layout::{Margin, Padding}; diff --git a/extensions/pagetop-bootsier/src/theme/classes/border.rs b/extensions/pagetop-bootsier/src/theme/classes/border.rs deleted file mode 100644 index 3095498c..00000000 --- a/extensions/pagetop-bootsier/src/theme/classes/border.rs +++ /dev/null @@ -1,175 +0,0 @@ -use pagetop::prelude::*; - -use crate::theme::aux::{BorderColor, Opacity, ScaleSize, Side}; - -/// Clases para crear **bordes**. -/// -/// Permite: -/// -/// - Iniciar un borde sin tamaño inicial (`Border::default()`). -/// - Crear un borde con tamaño por defecto (`Border::new()`). -/// - Ajustar el tamaño de cada **lado lógico** (`side`, respetando LTR/RTL). -/// - Definir un tamaño **global** para todo el borde (`size`). -/// - Aplicar un **color** al borde (`BorderColor`). -/// - Aplicar un nivel de **opacidad** (`Opacity`). -/// -/// # Comportamiento aditivo / sustractivo -/// -/// - **Aditivo**: basta con crear un borde sin tamaño con `classes::Border::default()` para ir -/// añadiendo cada lado lógico con el tamaño deseado usando `ScaleSize::{One..Five}`. -/// -/// - **Sustractivo**: se crea un borde con tamaño predefinido, p. ej. usando -/// `classes::Border::new()` o `classes::Border::with(ScaleSize::Two)` y eliminar los lados -/// deseados con `ScaleSize::Zero`. -/// -/// - **Anchos diferentes por lado**: usando `ScaleSize::{Zero..Five}` en cada lado deseado. -/// -/// # Ejemplos -/// -/// **Borde global:** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let b = classes::Border::with(ScaleSize::Two); -/// assert_eq!(b.to_class(), "border-2"); -/// ``` -/// -/// **Aditivo (solo borde superior):** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let b = classes::Border::default().with_side(Side::Top, ScaleSize::One); -/// assert_eq!(b.to_class(), "border-top-1"); -/// ``` -/// -/// **Sustractivo (borde global menos el superior):** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let b = classes::Border::new().with_side(Side::Top, ScaleSize::Zero); -/// assert_eq!(b.to_class(), "border border-top-0"); -/// ``` -/// -/// **Ancho por lado (lado lógico inicial a 2 y final a 4):** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let b = classes::Border::default() -/// .with_side(Side::Start, ScaleSize::Two) -/// .with_side(Side::End, ScaleSize::Four); -/// assert_eq!(b.to_class(), "border-end-4 border-start-2"); -/// ``` -/// -/// **Combinado (ejemplo completo):** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let b = classes::Border::new() // Borde por defecto. -/// .with_side(Side::Top, ScaleSize::Zero) // Quita borde superior. -/// .with_side(Side::End, ScaleSize::Three) // Ancho 3 para el lado lógico final. -/// .with_color(BorderColor::Theme(Color::Primary)) -/// .with_opacity(Opacity::Half); -/// -/// assert_eq!(b.to_class(), "border border-top-0 border-end-3 border-primary border-opacity-50"); -/// ``` -#[rustfmt::skip] -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub struct Border { - all : ScaleSize, - top : ScaleSize, - end : ScaleSize, - bottom : ScaleSize, - start : ScaleSize, - color : BorderColor, - opacity: Opacity, -} - -impl Border { - /// Prepara un borde del tamaño predefinido. Equivale a `border` (ancho por defecto del tema). - pub fn new() -> Self { - Self::with(ScaleSize::Auto) - } - - /// Crea un borde **con un tamaño global** (`size`). - pub fn with(size: ScaleSize) -> Self { - Self::default().with_side(Side::All, size) - } - - // **< Border BUILDER >************************************************************************* - - pub fn with_side(mut self, side: Side, size: ScaleSize) -> Self { - match side { - Side::All => self.all = size, - Side::Top => self.top = size, - Side::Bottom => self.bottom = size, - Side::Start => self.start = size, - Side::End => self.end = size, - Side::LeftAndRight => { - self.start = size; - self.end = size; - } - Side::TopAndBottom => { - self.top = size; - self.bottom = size; - } - }; - self - } - - /// Establece el color del borde. - pub fn with_color(mut self, color: BorderColor) -> Self { - self.color = color; - self - } - - /// Establece la opacidad del borde. - pub fn with_opacity(mut self, opacity: Opacity) -> Self { - self.opacity = opacity; - self - } - - // **< Border HELPERS >************************************************************************* - - /// Añade las clases de borde a la cadena de clases. - /// - /// Concatena, en este orden, las clases para *global*, `top`, `end`, `bottom`, `start`, - /// *color* y *opacidad*; respetando LTR/RTL y omitiendo las definiciones vacías. - #[rustfmt::skip] - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - self.all .push_class(classes, "border"); - self.top .push_class(classes, "border-top"); - self.end .push_class(classes, "border-end"); - self.bottom .push_class(classes, "border-bottom"); - self.start .push_class(classes, "border-start"); - self.color .push_class(classes); - self.opacity.push_class(classes, "border"); - } - - /// Devuelve las clases de borde como cadena (`"border-2"`, - /// `"border border-top-0 border-end-3 border-primary border-opacity-50"`, etc.). - /// - /// Si no se define ningún tamaño, color ni opacidad, devuelve `""`. - #[inline] - pub fn to_class(self) -> String { - let mut classes = String::new(); - self.push_class(&mut classes); - classes - } -} - -/// Atajo para crear un [`classes::Border`](crate::theme::classes::Border) a partir de un tamaño -/// [`ScaleSize`] aplicado a todo el borde. -/// -/// # Ejemplos -/// -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// // Convertir explícitamente con `From::from`: -/// let b = classes::Border::from(ScaleSize::Two); -/// assert_eq!(b.to_class(), "border-2"); -/// -/// // Convertir implícitamente con `into()`: -/// let b: classes::Border = ScaleSize::Auto.into(); -/// assert_eq!(b.to_class(), "border"); -/// ``` -impl From for Border { - fn from(size: ScaleSize) -> Self { - Self::with(size) - } -} diff --git a/extensions/pagetop-bootsier/src/theme/classes/color.rs b/extensions/pagetop-bootsier/src/theme/classes/color.rs deleted file mode 100644 index 162b7849..00000000 --- a/extensions/pagetop-bootsier/src/theme/classes/color.rs +++ /dev/null @@ -1,230 +0,0 @@ -use pagetop::prelude::*; - -use crate::theme::aux::{ColorBg, ColorText, Opacity}; - -// **< Background >********************************************************************************* - -/// Clases para establecer **color/opacidad del fondo**. -/// -/// # Ejemplos -/// -/// ``` -/// # use pagetop_bootsier::prelude::*; -/// // Sin clases. -/// let s = classes::Background::new(); -/// assert_eq!(s.to_class(), ""); -/// -/// // Sólo color de fondo. -/// let s = classes::Background::with(ColorBg::Theme(Color::Primary)); -/// assert_eq!(s.to_class(), "bg-primary"); -/// -/// // Color más opacidad. -/// let s = classes::Background::with(ColorBg::BodySecondary).with_opacity(Opacity::Half); -/// assert_eq!(s.to_class(), "bg-body-secondary bg-opacity-50"); -/// -/// // Usando `From`. -/// let s: classes::Background = ColorBg::Black.into(); -/// assert_eq!(s.to_class(), "bg-black"); -/// -/// // Usando `From<(ColorBg, Opacity)>`. -/// let s: classes::Background = (ColorBg::White, Opacity::SemiTransparent).into(); -/// assert_eq!(s.to_class(), "bg-white bg-opacity-25"); -/// ``` -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub struct Background { - color: ColorBg, - opacity: Opacity, -} - -impl Background { - /// Prepara un nuevo estilo para aplicar al fondo. - pub fn new() -> Self { - Self::default() - } - - /// Crea un estilo fijando el color de fondo (`bg-*`). - pub fn with(color: ColorBg) -> Self { - Self::default().with_color(color) - } - - // **< Background BUILDER >********************************************************************* - - /// Establece el color de fondo (`bg-*`). - pub fn with_color(mut self, color: ColorBg) -> Self { - self.color = color; - self - } - - /// Establece la opacidad del fondo (`bg-opacity-*`). - pub fn with_opacity(mut self, opacity: Opacity) -> Self { - self.opacity = opacity; - self - } - - // **< Background HELPERS >********************************************************************* - - /// Añade las clases de fondo a la cadena de clases. - /// - /// Concatena, en este orden, color del fondo (`bg-*`) y opacidad (`bg-opacity-*`), - /// omitiendo los fragmentos vacíos. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - self.color.push_class(classes); - self.opacity.push_class(classes, "bg"); - } - - /// Devuelve las clases de fondo como cadena (`"bg-primary"`, `"bg-body-secondary bg-opacity-50"`, etc.). - /// - /// Si no se define ni color ni opacidad, devuelve `""`. - #[inline] - pub fn to_class(self) -> String { - let mut classes = String::new(); - self.push_class(&mut classes); - classes - } -} - -impl From<(ColorBg, Opacity)> for Background { - /// Atajo para crear un [`classes::Background`](crate::theme::classes::Background) a partir del color de fondo y - /// la opacidad. - /// - /// # Ejemplo - /// - /// ``` - /// # use pagetop_bootsier::prelude::*; - /// let s: classes::Background = (ColorBg::White, Opacity::SemiTransparent).into(); - /// assert_eq!(s.to_class(), "bg-white bg-opacity-25"); - /// ``` - fn from((color, opacity): (ColorBg, Opacity)) -> Self { - Background::with(color).with_opacity(opacity) - } -} - -impl From for Background { - /// Atajo para crear un [`classes::Background`](crate::theme::classes::Background) a partir del color de fondo. - /// - /// # Ejemplo - /// - /// ``` - /// # use pagetop_bootsier::prelude::*; - /// let s: classes::Background = ColorBg::Black.into(); - /// assert_eq!(s.to_class(), "bg-black"); - /// ``` - fn from(color: ColorBg) -> Self { - Background::with(color) - } -} - -// **< Text >*************************************************************************************** - -/// Clases para establecer **color/opacidad del texto**. -/// -/// # Ejemplos -/// -/// ``` -/// # use pagetop_bootsier::prelude::*; -/// // Sin clases. -/// let s = classes::Text::new(); -/// assert_eq!(s.to_class(), ""); -/// -/// // Sólo color del texto. -/// let s = classes::Text::with(ColorText::Theme(Color::Primary)); -/// assert_eq!(s.to_class(), "text-primary"); -/// -/// // Color del texto y opacidad. -/// let s = classes::Text::new().with_color(ColorText::White).with_opacity(Opacity::SemiTransparent); -/// assert_eq!(s.to_class(), "text-white text-opacity-25"); -/// -/// // Usando `From`. -/// let s: classes::Text = ColorText::Black.into(); -/// assert_eq!(s.to_class(), "text-black"); -/// -/// // Usando `From<(ColorText, Opacity)>`. -/// let s: classes::Text = (ColorText::Theme(Color::Danger), Opacity::Opaque).into(); -/// assert_eq!(s.to_class(), "text-danger text-opacity-100"); -/// ``` -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub struct Text { - color: ColorText, - opacity: Opacity, -} - -impl Text { - /// Prepara un nuevo estilo para aplicar al texto. - pub fn new() -> Self { - Self::default() - } - - /// Crea un estilo fijando el color del texto (`text-*`). - pub fn with(color: ColorText) -> Self { - Self::default().with_color(color) - } - - // **< Text BUILDER >*************************************************************************** - - /// Establece el color del texto (`text-*`). - pub fn with_color(mut self, color: ColorText) -> Self { - self.color = color; - self - } - - /// Establece la opacidad del texto (`text-opacity-*`). - pub fn with_opacity(mut self, opacity: Opacity) -> Self { - self.opacity = opacity; - self - } - - // **< Text HELPERS >*************************************************************************** - - /// Añade las clases de texto a la cadena de clases. - /// - /// Concatena, en este orden, `text-*` y `text-opacity-*`, omitiendo los fragmentos vacíos. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - self.color.push_class(classes); - self.opacity.push_class(classes, "text"); - } - - /// Devuelve las clases de texto como cadena (`"text-primary"`, `"text-white text-opacity-25"`, - /// etc.). - /// - /// Si no se define ni color ni opacidad, devuelve `""`. - #[inline] - pub fn to_class(self) -> String { - let mut classes = String::new(); - self.push_class(&mut classes); - classes - } -} - -impl From<(ColorText, Opacity)> for Text { - /// Atajo para crear un [`classes::Text`](crate::theme::classes::Text) a partir del color del - /// texto y su opacidad. - /// - /// # Ejemplo - /// - /// ``` - /// # use pagetop_bootsier::prelude::*; - /// let s: classes::Text = (ColorText::Theme(Color::Danger), Opacity::Opaque).into(); - /// assert_eq!(s.to_class(), "text-danger text-opacity-100"); - /// ``` - fn from((color, opacity): (ColorText, Opacity)) -> Self { - Text::with(color).with_opacity(opacity) - } -} - -impl From for Text { - /// Atajo para crear un [`classes::Text`](crate::theme::classes::Text) a partir del color del - /// texto. - /// - /// # Ejemplo - /// - /// ``` - /// # use pagetop_bootsier::prelude::*; - /// let s: classes::Text = ColorText::Black.into(); - /// assert_eq!(s.to_class(), "text-black"); - /// ``` - fn from(color: ColorText) -> Self { - Text::with(color) - } -} diff --git a/extensions/pagetop-bootsier/src/theme/classes/layout.rs b/extensions/pagetop-bootsier/src/theme/classes/layout.rs deleted file mode 100644 index e9d7e248..00000000 --- a/extensions/pagetop-bootsier/src/theme/classes/layout.rs +++ /dev/null @@ -1,205 +0,0 @@ -use pagetop::prelude::*; - -use crate::theme::aux::{ScaleSize, Side}; -use crate::theme::BreakPoint; - -// **< Margin >************************************************************************************* - -/// Clases para establecer **margin** por lado, tamaño y punto de ruptura. -/// -/// # Ejemplos -/// -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let m = classes::Margin::with(Side::Top, ScaleSize::Three); -/// assert_eq!(m.to_class(), "mt-3"); -/// -/// let m = classes::Margin::with(Side::Start, ScaleSize::Auto).with_breakpoint(BreakPoint::LG); -/// assert_eq!(m.to_class(), "ms-lg-auto"); -/// -/// let m = classes::Margin::with(Side::All, ScaleSize::None); -/// assert_eq!(m.to_class(), ""); -/// ``` -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub struct Margin { - side: Side, - size: ScaleSize, - breakpoint: BreakPoint, -} - -impl Margin { - /// Crea un **margin** indicando lado(s) y tamaño. Por defecto no se aplica a ningún punto de - /// ruptura. - pub fn with(side: Side, size: ScaleSize) -> Self { - Margin { - side, - size, - breakpoint: BreakPoint::None, - } - } - - // **< Margin BUILDER >************************************************************************* - - /// Establece el punto de ruptura a partir del cual se empieza a aplicar el **margin**. - pub fn with_breakpoint(mut self, breakpoint: BreakPoint) -> Self { - self.breakpoint = breakpoint; - self - } - - // **< Margin HELPERS >************************************************************************* - - // Devuelve el prefijo `m*` según el lado. - #[rustfmt::skip] - #[inline] - const fn side_prefix(&self) -> &'static str { - match self.side { - Side::All => "m", - Side::Top => "mt", - Side::Bottom => "mb", - Side::Start => "ms", - Side::End => "me", - Side::LeftAndRight => "mx", - Side::TopAndBottom => "my", - } - } - - // Devuelve el sufijo del tamaño (`auto`, `0`..`5`), o `None` si no define clase. - #[rustfmt::skip] - #[inline] - const fn size_suffix(&self) -> Option<&'static str> { - match self.size { - ScaleSize::None => None, - ScaleSize::Auto => Some("auto"), - ScaleSize::Zero => Some("0"), - ScaleSize::One => Some("1"), - ScaleSize::Two => Some("2"), - ScaleSize::Three => Some("3"), - ScaleSize::Four => Some("4"), - ScaleSize::Five => Some("5"), - } - } - - /* Añade la clase de **margin** a la cadena de clases (reservado). - // - // No añade nada si `size` es `ScaleSize::None`. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - let Some(size) = self.size_suffix() else { - return; - }; - self.breakpoint - .push_class(classes, self.side_prefix(), size); - } */ - - /// Devuelve la clase de **margin** como cadena (`"mt-3"`, `"ms-lg-auto"`, etc.). - /// - /// Si `size` es `ScaleSize::None`, devuelve `""`. - #[inline] - pub fn to_class(self) -> String { - let Some(size) = self.size_suffix() else { - return String::new(); - }; - self.breakpoint.class_with(self.side_prefix(), size) - } -} - -// **< Padding >************************************************************************************ - -/// Clases para establecer **padding** por lado, tamaño y punto de ruptura. -/// -/// # Ejemplos -/// -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let p = classes::Padding::with(Side::LeftAndRight, ScaleSize::Two); -/// assert_eq!(p.to_class(), "px-2"); -/// -/// let p = classes::Padding::with(Side::End, ScaleSize::Four).with_breakpoint(BreakPoint::SM); -/// assert_eq!(p.to_class(), "pe-sm-4"); -/// -/// let p = classes::Padding::with(Side::All, ScaleSize::Auto); -/// assert_eq!(p.to_class(), ""); // `Auto` no aplica a padding. -/// ``` -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub struct Padding { - side: Side, - size: ScaleSize, - breakpoint: BreakPoint, -} - -impl Padding { - /// Crea un **padding** indicando lado(s) y tamaño. Por defecto no se aplica a ningún punto de - /// ruptura. - pub fn with(side: Side, size: ScaleSize) -> Self { - Padding { - side, - size, - breakpoint: BreakPoint::None, - } - } - - // **< Padding BUILDER >************************************************************************ - - /// Establece el punto de ruptura a partir del cual se empieza a aplicar el **padding**. - pub fn with_breakpoint(mut self, breakpoint: BreakPoint) -> Self { - self.breakpoint = breakpoint; - self - } - - // **< Padding HELPERS >************************************************************************ - - // Devuelve el prefijo `p*` según el lado. - #[rustfmt::skip] - #[inline] - const fn prefix(&self) -> &'static str { - match self.side { - Side::All => "p", - Side::Top => "pt", - Side::Bottom => "pb", - Side::Start => "ps", - Side::End => "pe", - Side::LeftAndRight => "px", - Side::TopAndBottom => "py", - } - } - - // Devuelve el sufijo del tamaño (`0`..`5`), o `None` si no define clase. - // - // Nota: `ScaleSize::Auto` **no aplica** a padding ⇒ devuelve `None`. - #[rustfmt::skip] - #[inline] - const fn suffix(&self) -> Option<&'static str> { - match self.size { - ScaleSize::None => None, - ScaleSize::Auto => None, - ScaleSize::Zero => Some("0"), - ScaleSize::One => Some("1"), - ScaleSize::Two => Some("2"), - ScaleSize::Three => Some("3"), - ScaleSize::Four => Some("4"), - ScaleSize::Five => Some("5"), - } - } - - /* Añade la clase de **padding** a la cadena de clases (reservado). - // - // No añade nada si `size` es `ScaleSize::None` o `ScaleSize::Auto`. - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - let Some(size) = self.suffix() else { - return; - }; - self.breakpoint.push_class(classes, self.prefix(), size); - } */ - - // Devuelve la clase de **padding** como cadena (`"px-2"`, `"pe-sm-4"`, etc.). - // - // Si `size` es `ScaleSize::None` o `ScaleSize::Auto`, devuelve `""`. - #[inline] - pub fn to_class(self) -> String { - let Some(size) = self.suffix() else { - return String::new(); - }; - self.breakpoint.class_with(self.prefix(), size) - } -} diff --git a/extensions/pagetop-bootsier/src/theme/classes/rounded.rs b/extensions/pagetop-bootsier/src/theme/classes/rounded.rs deleted file mode 100644 index 58d50b86..00000000 --- a/extensions/pagetop-bootsier/src/theme/classes/rounded.rs +++ /dev/null @@ -1,169 +0,0 @@ -use pagetop::prelude::*; - -use crate::theme::aux::RoundedRadius; - -/// Clases para definir **esquinas redondeadas**. -/// -/// Permite: -/// -/// - Definir un radio **global para todas las esquinas** (`radius`). -/// - Ajustar el radio asociado a las **esquinas de cada lado lógico** (`top`, `end`, `bottom`, -/// `start`, **en este orden**, respetando LTR/RTL). -/// - Ajustar el radio de las **esquinas concretas** (`top-start`, `top-end`, `bottom-start`, -/// `bottom-end`, **en este orden**, respetando LTR/RTL). -/// -/// # Ejemplos -/// -/// **Radio global:** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let r = classes::Rounded::with(RoundedRadius::Default); -/// assert_eq!(r.to_class(), "rounded"); -/// ``` -/// -/// **Sin redondeo:** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let r = classes::Rounded::new(); -/// assert_eq!(r.to_class(), ""); -/// ``` -/// -/// **Radio en las esquinas de un lado lógico:** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let r = classes::Rounded::new().with_end(RoundedRadius::Scale2); -/// assert_eq!(r.to_class(), "rounded-end-2"); -/// ``` -/// -/// **Radio en una esquina concreta:** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let r = classes::Rounded::new().with_top_start(RoundedRadius::Scale3); -/// assert_eq!(r.to_class(), "rounded-top-start-3"); -/// ``` -/// -/// **Combinado (ejemplo completo):** -/// ```rust -/// # use pagetop_bootsier::prelude::*; -/// let r = classes::Rounded::new() -/// .with_top(RoundedRadius::Default) // Añade redondeo arriba. -/// .with_bottom_start(RoundedRadius::Scale4) // Añade una esquina redondeada concreta. -/// .with_bottom_end(RoundedRadius::Circle); // Añade redondeo extremo en otra esquina. -/// -/// assert_eq!(r.to_class(), "rounded-top rounded-bottom-start-4 rounded-bottom-end-circle"); -/// ``` -#[rustfmt::skip] -#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] -pub struct Rounded { - radius : RoundedRadius, - top : RoundedRadius, - end : RoundedRadius, - bottom : RoundedRadius, - start : RoundedRadius, - top_start : RoundedRadius, - top_end : RoundedRadius, - bottom_start: RoundedRadius, - bottom_end : RoundedRadius, -} - -impl Rounded { - /// Prepara las esquinas **sin redondeo global** de partida. - pub fn new() -> Self { - Self::default() - } - - /// Crea las esquinas **con redondeo global** (`radius`). - pub fn with(radius: RoundedRadius) -> Self { - Self::default().with_radius(radius) - } - - // **< Rounded BUILDER >************************************************************************ - - /// Establece el radio global de las esquinas (`rounded*`). - pub fn with_radius(mut self, radius: RoundedRadius) -> Self { - self.radius = radius; - self - } - - /// Establece el radio en las esquinas del lado superior (`rounded-top-*`). - pub fn with_top(mut self, radius: RoundedRadius) -> Self { - self.top = radius; - self - } - - /// Establece el radio en las esquinas del lado lógico final (`rounded-end-*`). Respeta LTR/RTL. - pub fn with_end(mut self, radius: RoundedRadius) -> Self { - self.end = radius; - self - } - - /// Establece el radio en las esquinas del lado inferior (`rounded-bottom-*`). - pub fn with_bottom(mut self, radius: RoundedRadius) -> Self { - self.bottom = radius; - self - } - - /// Establece el radio en las esquinas del lado lógico inicial (`rounded-start-*`). Respeta - /// LTR/RTL. - pub fn with_start(mut self, radius: RoundedRadius) -> Self { - self.start = radius; - self - } - - /// Establece el radio en la esquina superior-inicial (`rounded-top-start-*`). Respeta LTR/RTL. - pub fn with_top_start(mut self, radius: RoundedRadius) -> Self { - self.top_start = radius; - self - } - - /// Establece el radio en la esquina superior-final (`rounded-top-end-*`). Respeta LTR/RTL. - pub fn with_top_end(mut self, radius: RoundedRadius) -> Self { - self.top_end = radius; - self - } - - /// Establece el radio en la esquina inferior-inicial (`rounded-bottom-start-*`). Respeta - /// LTR/RTL. - pub fn with_bottom_start(mut self, radius: RoundedRadius) -> Self { - self.bottom_start = radius; - self - } - - /// Establece el radio en la esquina inferior-final (`rounded-bottom-end-*`). Respeta LTR/RTL. - pub fn with_bottom_end(mut self, radius: RoundedRadius) -> Self { - self.bottom_end = radius; - self - } - - // **< Rounded HELPERS >************************************************************************ - - /// Añade las clases de redondeo a la cadena de clases. - /// - /// Concatena, en este orden, las clases para *global*, `top`, `end`, `bottom`, `start`, - /// `top-start`, `top-end`, `bottom-start` y `bottom-end`; respetando LTR/RTL y omitiendo las - /// definiciones vacías. - #[rustfmt::skip] - #[inline] - pub(crate) fn push_class(self, classes: &mut String) { - self.radius .push_class(classes, ""); - self.top .push_class(classes, "rounded-top"); - self.end .push_class(classes, "rounded-end"); - self.bottom .push_class(classes, "rounded-bottom"); - self.start .push_class(classes, "rounded-start"); - self.top_start .push_class(classes, "rounded-top-start"); - self.top_end .push_class(classes, "rounded-top-end"); - self.bottom_start.push_class(classes, "rounded-bottom-start"); - self.bottom_end .push_class(classes, "rounded-bottom-end"); - } - - /// Devuelve las clases de redondeo como cadena (`"rounded"`, - /// `"rounded-top rounded-bottom-start-4 rounded-bottom-end-circle"`, etc.). - /// - /// Si no se define ningún radio, devuelve `""`. - #[inline] - pub fn to_class(self) -> String { - let mut classes = String::new(); - self.push_class(&mut classes); - classes - } -} diff --git a/extensions/pagetop-bootsier/src/theme/container.rs b/extensions/pagetop-bootsier/src/theme/container.rs deleted file mode 100644 index a860110f..00000000 --- a/extensions/pagetop-bootsier/src/theme/container.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! Definiciones para crear contenedores de componentes ([`Container`]). -//! -//! Cada contenedor envuelve contenido usando la etiqueta semántica indicada por -//! [`container::Kind`](crate::theme::container::Kind). -//! -//! Con [`container::Width`](crate::theme::container::Width) se puede definir el ancho y el -//! comportamiento *responsive* del contenedor. También permite aplicar utilidades de estilo para el -//! fondo, texto, borde o esquinas redondeadas. -//! -//! # Ejemplo -//! -//! ```rust -//! # use pagetop::prelude::*; -//! # use pagetop_bootsier::prelude::*; -//! let main = Container::main() -//! .with_id("main-page") -//! .with_width(container::Width::From(BreakPoint::LG)); -//! ``` - -mod props; -pub use props::{Kind, Width}; - -mod component; -pub use component::Container; diff --git a/extensions/pagetop-bootsier/src/theme/container/component.rs b/extensions/pagetop-bootsier/src/theme/container/component.rs deleted file mode 100644 index 068d24a3..00000000 --- a/extensions/pagetop-bootsier/src/theme/container/component.rs +++ /dev/null @@ -1,184 +0,0 @@ -use pagetop::prelude::*; - -use crate::prelude::*; - -/// Componente para crear un **contenedor de componentes**. -/// -/// Envuelve un contenido con la etiqueta HTML indicada por [`container::Kind`]. Sólo se renderiza -/// si existen componentes hijos (*children*). -#[rustfmt::skip] -#[derive(AutoDefault)] -pub struct Container { - id : AttrId, - classes : AttrClasses, - container_kind : container::Kind, - container_width: container::Width, - children : Children, -} - -impl Component for Container { - fn new() -> Self { - Container::default() - } - - fn id(&self) -> Option { - self.id.get() - } - - fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.alter_classes(ClassesOp::Prepend, self.width().to_class()); - } - - fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { - let output = self.children().render(cx); - if output.is_empty() { - return PrepareMarkup::None; - } - let style = match self.width() { - container::Width::FluidMax(w) if w.is_measurable() => { - Some(join!("max-width: ", w.to_string(), ";")) - } - _ => None, - }; - match self.container_kind() { - container::Kind::Default => PrepareMarkup::With(html! { - div id=[self.id()] class=[self.classes().get()] style=[style] { - (output) - } - }), - container::Kind::Main => PrepareMarkup::With(html! { - main id=[self.id()] class=[self.classes().get()] style=[style] { - (output) - } - }), - container::Kind::Header => PrepareMarkup::With(html! { - header id=[self.id()] class=[self.classes().get()] style=[style] { - (output) - } - }), - container::Kind::Footer => PrepareMarkup::With(html! { - footer id=[self.id()] class=[self.classes().get()] style=[style] { - (output) - } - }), - container::Kind::Section => PrepareMarkup::With(html! { - section id=[self.id()] class=[self.classes().get()] style=[style] { - (output) - } - }), - container::Kind::Article => PrepareMarkup::With(html! { - article id=[self.id()] class=[self.classes().get()] style=[style] { - (output) - } - }), - } - } -} - -impl Container { - /// Crea un contenedor de tipo `Main` (`
`). - pub fn main() -> Self { - Container { - container_kind: container::Kind::Main, - ..Default::default() - } - } - - /// Crea un contenedor de tipo `Header` (`
`). - pub fn header() -> Self { - Container { - container_kind: container::Kind::Header, - ..Default::default() - } - } - - /// Crea un contenedor de tipo `Footer` (`