Initial Commit

This commit is contained in:
gabatxo1312 2026-01-23 13:56:30 +01:00
commit e8529bdbee
25 changed files with 13519 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

970
Cargo.lock generated Normal file
View File

@ -0,0 +1,970 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "askama"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7125972258312e79827b60c9eb93938334100245081cf701a2dee981b17427"
dependencies = [
"askama_macros",
"itoa",
"percent-encoding",
"serde",
"serde_json",
]
[[package]]
name = "askama_derive"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ba5e7259a1580c61571e3116ebaaa01e3c001b2132b17c4cc5c70780ca3e994"
dependencies = [
"askama_parser",
"basic-toml",
"memchr",
"proc-macro2",
"quote",
"rustc-hash",
"serde",
"serde_derive",
"syn",
]
[[package]]
name = "askama_macros"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "236ce20b77cb13506eaf5024899f4af6e12e8825f390bd943c4c37fd8f322e46"
dependencies = [
"askama_derive",
]
[[package]]
name = "askama_parser"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c63392767bb2df6aa65a6e1e3b80fd89bb7af6d58359b924c0695620f1512e"
dependencies = [
"rustc-hash",
"serde",
"serde_derive",
"unicode-ident",
"winnow",
]
[[package]]
name = "askama_web"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5911a65ac3916ef133167a855d52978f9fbf54680a093e0ef29e20b7e94a4523"
dependencies = [
"askama",
"askama_web_derive",
"axum-core",
"bytes",
"http",
]
[[package]]
name = "askama_web_derive"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9767c17d33a63daf6da5872ffaf2ab0c289cd73ce7ed4f41d5ddf9149c004873"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "axum"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
dependencies = [
"axum-core",
"bytes",
"form_urlencoded",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-util",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"serde_core",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-core"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"sync_wrapper",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "basic-toml"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
dependencies = [
"serde",
]
[[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 = "bookforge"
version = "0.1.0"
dependencies = [
"askama",
"askama_web",
"axum",
"serde",
"static-serve",
"tokio",
]
[[package]]
name = "bytes"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
[[package]]
name = "cc"
version = "1.2.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[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 = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "display_full_error"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7c47e9a2fd28a8edd1446f10dabe8ac5d26bb77ed2b1077bfcd8308904e8c6"
[[package]]
name = "find-msvc-tools"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
[[package]]
name = "flate2"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[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-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[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",
]
[[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.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
]
[[package]]
name = "glob"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
]
[[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 = "hyper"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
dependencies = [
"atomic-waker",
"bytes",
"futures-channel",
"futures-core",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"pin-utils",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-util"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"hyper",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom",
"libc",
]
[[package]]
name = "libc"
version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "matchit"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[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.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
dependencies = [
"libc",
"wasi",
"windows-sys 0.61.2",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[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 = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
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 = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "ryu"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[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.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
dependencies = [
"itoa",
"serde",
"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 = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simd-adler32"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
dependencies = [
"libc",
"windows-sys 0.60.2",
]
[[package]]
name = "static-serve"
version = "0.4.0"
source = "git+https://github.com/M4SS-Code/static-serve#070fd02ffede7abebf0d773103e6f16c122d4142"
dependencies = [
"axum",
"bytes",
"static-serve-macro",
]
[[package]]
name = "static-serve-macro"
version = "0.4.0"
source = "git+https://github.com/M4SS-Code/static-serve#070fd02ffede7abebf0d773103e6f16c122d4142"
dependencies = [
"display_full_error",
"flate2",
"glob",
"mime_guess",
"proc-macro2",
"quote",
"sha1",
"syn",
"thiserror",
"zstd",
]
[[package]]
name = "syn"
version = "2.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio"
version = "1.49.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
dependencies = [
"libc",
"mio",
"pin-project-lite",
"socket2",
"tokio-macros",
"windows-sys 0.61.2",
]
[[package]]
name = "tokio-macros"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tower"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"log",
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
dependencies = [
"once_cell",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicase"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasip2"
version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets",
]
[[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.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[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.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[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.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[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.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[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.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]]
name = "zmij"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65"
[[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",
]

22
Cargo.toml Normal file
View File

@ -0,0 +1,22 @@
[package]
name = "bookforge"
version = "0.1.0"
edition = "2024"
[lib]
name = "bookforge"
path = "src/lib.rs"
[[bin]]
name = "bookforge"
path = "src/main.rs"
[dependencies]
askama = "0.15.1"
askama_web = { version = "0.15.1", features = ["axum-0.8"] }
axum = "0.8.8"
serde = "1.0.228"
# static-serve = "0.4.0"
static-serve = { git = "https://github.com/M4SS-Code/static-serve" }
tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread"] }

12048
assets/css/bootstrap.css vendored Normal file

File diff suppressed because it is too large Load Diff

3
assets/css/main.css Normal file
View File

@ -0,0 +1,3 @@
.mt-50px {
margin-top: 50px;
}

7
assets/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

29
assets/js/script.js Normal file
View File

@ -0,0 +1,29 @@
// @description Get cookie by name
function getCookie(name) {
return document.cookie
.split("; ")
.find(row => row.startsWith(name + "="))
?.split("=")[1];
}
const DEFAULT_THEME = 'light'
window.addEventListener('load', (e) => {
let theme = getCookie('theme');
if (theme) {
// change theme
document.querySelector('html').setAttribute("data-bs-theme", theme);
// update value of input
document.querySelector("#changeTheme").value = theme
} else {
document.querySelector('html').setAttribute("data-bs-theme", DEFAULT_THEME);
}
});
document.querySelector("#changeTheme").addEventListener('change', (e) => {
// create cookie to save theme preferences
document.cookie = `theme=${e.target.value}; path=/; max-age=31536000`;
//change theme
document.querySelector('html').setAttribute("data-bs-theme", e.target.value);
});

17
src/error.rs Normal file
View File

@ -0,0 +1,17 @@
use askama::Template;
use askama_web::WebTemplate;
use axum::response::{IntoResponse, Response};
#[derive(Template, WebTemplate)]
#[template(path = "error.html")]
struct ErrorTemplate {}
pub enum AppStateError {
Error,
}
impl IntoResponse for AppStateError {
fn into_response(self) -> Response {
ErrorTemplate {}.into_response()
}
}

17
src/lib.rs Normal file
View File

@ -0,0 +1,17 @@
use axum::{Router, routing::get};
use static_serve::embed_assets;
mod error;
mod routes;
pub fn build_app() -> Router {
embed_assets!("assets", compress = true);
Router::new()
.route("/", get(routes::book::index))
.route("/books/{id}", get(routes::book::show))
.route("/books/{id}/edit", get(routes::book::edit))
.route("/books/new", get(routes::book::new))
.route("/users", get(routes::user::index))
.nest("/assets", static_router())
}

10
src/main.rs Normal file
View File

@ -0,0 +1,10 @@
use bookforge::build_app;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let app = build_app();
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
let _ = axum::serve(listener, app).await;
}

57
src/routes/book.rs Normal file
View File

@ -0,0 +1,57 @@
use askama::Template;
use askama_web::WebTemplate;
use axum::extract::Path;
use crate::error::AppStateError;
#[derive(Template, WebTemplate)]
#[template(path = "index.html")]
struct BookIndexTemplate {}
pub async fn index() -> Result<impl axum::response::IntoResponse, AppStateError> {
if 0 > 1 {
return Err(AppStateError::Error);
}
Ok(BookIndexTemplate {})
}
#[derive(Template, WebTemplate)]
#[template(path = "books/show.html")]
struct ShowBookTemplate {}
pub async fn show(
Path(_id): Path<i32>,
) -> Result<impl axum::response::IntoResponse, AppStateError> {
if 0 > 1 {
return Err(AppStateError::Error);
}
Ok(ShowBookTemplate {})
}
#[derive(Template, WebTemplate)]
#[template(path = "books/new.html")]
struct NewBookTemplate {}
pub async fn new() -> Result<impl axum::response::IntoResponse, AppStateError> {
if 0 > 1 {
return Err(AppStateError::Error);
}
Ok(NewBookTemplate {})
}
#[derive(Template, WebTemplate)]
#[template(path = "books/edit.html")]
struct EditBookTemplate {}
pub async fn edit(
Path(_id): Path<i32>,
) -> Result<impl axum::response::IntoResponse, AppStateError> {
if 0 > 1 {
return Err(AppStateError::Error);
}
Ok(EditBookTemplate {})
}

2
src/routes/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod book;
pub mod user;

16
src/routes/user.rs Normal file
View File

@ -0,0 +1,16 @@
use askama::Template;
use askama_web::WebTemplate;
use crate::error::AppStateError;
#[derive(Template, WebTemplate)]
#[template(path = "users/index.html")]
struct UsersIndexTemplate {}
pub async fn index() -> Result<impl axum::response::IntoResponse, AppStateError> {
if 0 > 1 {
return Err(AppStateError::Error);
}
Ok(UsersIndexTemplate {})
}

32
templates/base.html Normal file
View File

@ -0,0 +1,32 @@
<html data-bs-theme="light">
<head>
<meta charset="utf-8">
<title>{% block title %}Book Forge{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/assets/css/bootstrap.css">
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="stylesheet" href="/assets/css/fork-awesome.min.css">
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
{% block extra_head %}{% endblock extra_head %}
</head>
<body class="d-flex flex-column min-vh-100">
{% include "layout/header.html" %}
<main class="container" style="padding-top: 100px;">
{% block main %}{% endblock %}
</main>
<footer class="text-center mt-auto pt-4">
{% block footer_extra %}
{% include "layout/footer.html" %}
{% endblock %}
</footer>
<script src="/assets/js/bootstrap.min.js"></script>
<script src="/assets/js/script.js"></script>
</body>
</html>

49
templates/books/edit.html Normal file
View File

@ -0,0 +1,49 @@
{% extends "base.html" %}
{% import "components/typography.html" as typography %}
{% block main %}
{{ typography::heading("Editer La petite derniere") }}
<form>
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" class="form-control" value="La petite derniere">
</div>
<div class="mb-3">
<label class="form-label">Author(s)</label>
<input type="text" class="form-control" value="Fatima Daas">
</div>
<div class="mb-3">
<label class="form-label">Owner</label>
<select class="form-control">
<option selected>Jean</option>
<option>Simon</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Current Holder</label>
<select class="form-control">
<option></option>
<option>Jean</option>
<option selected>Simon</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<textarea class="form-control">dsjfskdljf</textarea>
</div>
<div class="mb-3">
<label class="form-label">Comment</label>
<textarea class="form-control">sdsfjsdkfjsdklfj</textarea>
</div>
<div class="mt-4 text-center">
<input type="submit" value="Create book" class="btn btn-success">
</div>
</form>
{% endblock %}

49
templates/books/new.html Normal file
View File

@ -0,0 +1,49 @@
{% extends "base.html" %}
{% import "components/typography.html" as typography %}
{% block main %}
{{ typography::heading("New book") }}
<form>
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" class="form-control">
</div>
<div class="mb-3">
<label class="form-label">Author(s)</label>
<input type="text" class="form-control">
</div>
<div class="mb-3">
<label class="form-label">Owner</label>
<select class="form-control">
<option>Jean</option>
<option>Simon</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Current Holder</label>
<select class="form-control">
<option></option>
<option>Jean</option>
<option>Simon</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<textarea class="form-control"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Comment</label>
<textarea class="form-control"></textarea>
</div>
<div class="mt-4 text-center">
<input type="submit" value="Create book" class="btn btn-success">
</div>
</form>
{% endblock %}

31
templates/books/show.html Normal file
View File

@ -0,0 +1,31 @@
{% extends "base.html" %}
{% import "components/typography.html" as typography %}
{% import "components/dropdown.html" as dropdown %}
{% import "components/fields.html" as fields %}
{% block main %}
{% call typography::heading("La petite derniere") %}
{{ dropdown::dropdown_button("Actions", [("Edit", "/books/1/edit"), ("Delete", "/books/1")]) }}
{% endcall %}
<div class="mt-4">
<h5 class="mt-4 fw-bold">Book details</h5>
{{ fields::field("Name", "La petite derniere") }}
{{ fields::field("Authors", "Fatima Daas") }}
{{ fields::field("Authors", "Je mappelle Fatima Daas. Je suis la mazoziya, la petite dernière. Celle à laquelle on ne
sest pas préparé. Française dorigine algérienne. Musulmane pratiquante. Clichoise qui passe plus de trois heures par
jour dans les transports. Une touriste. Une banlieusarde qui observe les comportements parisiens. Je suis une
menteuse, une pécheresse. Adolescente, je suis une élève instable. Adulte, je suis hyper-inadaptée. Jécris des
histoires pour éviter de vivre la mienne. Jai fait quatre ans de thérapie. Cest ma plus longue relation. Lamour,
cétait tabou à la maison, les marques de tendresse, la sexualité aussi. Je me croyais polyamoureuse. Lorsque Nina a
débarqué dans ma vie, je ne savais plus du tout ce dont javais besoin et ce quil me manquait. Je mappelle Fatima
Daas. Je ne sais pas si je porte bien mon prénom.") }}
<h5 class="mt-50px fw-bold">User Details</h5>
{{ fields::field("Owner", "Jean") }}
{{ fields::field("Current Holder", "Pierre") }}
<h5 class="mt-50px fw-bold">More Informations</h5>
{{ fields::field("Comment", "J'adore ce livre ca parle de plein de choses !") }}
</div>
{% endblock %}

View File

@ -0,0 +1,12 @@
{% macro dropdown_button(label, items = []) %}
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ label }}
</button>
<ul class="dropdown-menu">
{% for item in items %}
<li><a class="dropdown-item" href="{{ item.1 }}">{{ item.0 }}</a></li>
{% endfor %}
</ul>
</div>
{% endmacro %}

View File

@ -0,0 +1,14 @@
{% macro field(name, value) %}
<div class="row mt-4">
<div class="col-md-3">
<p class="mb-0 fw-regular">
{{ name }}:
</p>
</div>
<div class="col-md-9">
<p class="mb-0">
{{ value }}
</p>
</div>
</div>
{% endmacro %}

View File

@ -0,0 +1,13 @@
{% macro heading(title) %}
<div class="d-flex justify-content-between align-items-center">
<h1 class="mb-4">
{{ title }}
</h1>
{% if caller is defined %}
<div>
{{ caller() }}
</div>
{% endif %}
</div>
{% endmacro %}

1
templates/error.html Normal file
View File

@ -0,0 +1 @@
Error

41
templates/index.html Normal file
View File

@ -0,0 +1,41 @@
{% extends "base.html" %}
{% import "components/typography.html" as typography %}
{% import "components/dropdown.html" as dropdown %}
{% block main %}
{{ typography::heading("All books") }}
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Author(s)</th>
<th scope="col">Owner</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>La petite derniere</td>
<td>Fatima Daas</td>
<td>Jean</td>
<td>
{{ dropdown::dropdown_button("Actions", [("Voir", "/books/1"), ("Edit", "/books/1/edit"), ("Delete",
"/books/1")]) }}
</td>
</tr>
<tr>
<th scope="row">2</th>
<td>La petite derniere</td>
<td>Fatima Daas</td>
<td>Jean</td>
<td>
{{ dropdown::dropdown_button("Actions", [("Voir", "/books/1"), ("Edit", "/books/1/edit"), ("Delete",
"/books/1")]) }}
</td>
</tr>
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,5 @@
<div class="container text-center mt-4">
<div class="d-flex flex-column flex-sm-row gap-0 gap-sm-3 justify-content-center">
<p>Made with Love & Fuck a Fascist !</p>
</div>
</div>

View File

@ -0,0 +1,34 @@
<nav class="navbar navbar-expand-lg bg-body-tertiary fixed-top shadow">
<div class="container">
<a class="navbar-brand" href="/">
BookForge
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="/">Books</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/users">Users</a>
</li>
</ul>
<div class="d-flex align-items-center gap-2 py-3">
<select id="changeTheme" class="form-select">
<option value="light">light</option>
<option value="dark">dark</option>
</select>
<a class="btn btn-success text-white" href="/books/new">
<i class="fa fa-download me-2"></i>
Add&nbsp;book
</a>
</div>
</div>
</div>
</nav>

View File

@ -0,0 +1,39 @@
{% extends "base.html" %}
{% import "components/typography.html" as typography %}
{% block main %}
{{ typography::heading("All users") }}
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Nombre de livres</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Jean</td>
<td>34</td>
<td>
<a href='#' class="btn btn-danger btn-sm">
Delete
</a>
</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Pierre</td>
<td>34</td>
<td>
<a href='#' class="btn btn-danger btn-sm">
Delete
</a>
</td>
</tr>
</tbody>
</table>
{% endblock %}