diff --git a/Cargo.lock b/Cargo.lock index 990b25b..dec2400 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,12 +434,6 @@ version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "byteorder-lite" version = "0.1.0" @@ -738,29 +732,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cssparser" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e901edd733a1472f944a45116df3f846f54d37e67e68640ac8bb69689aca2aa" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "phf 0.11.3", - "smallvec", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn 2.0.117", -] - [[package]] name = "deranged" version = "0.5.8" @@ -805,26 +776,6 @@ dependencies = [ "syn 2.0.117", ] -[[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 2.0.117", -] - [[package]] name = "diff" version = "0.1.13" @@ -900,27 +851,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" -[[package]] -name = "dtoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" - -[[package]] -name = "dtoa-short" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" -dependencies = [ - "dtoa", -] - -[[package]] -name = "ego-tree" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2972feb8dffe7bc8c5463b1dacda1b0dfbed3710e50f977d965429692d74cd8" - [[package]] name = "either" version = "1.15.0" @@ -999,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1028,12 +958,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - [[package]] name = "fax" version = "0.2.6" @@ -1086,12 +1010,6 @@ 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" @@ -1111,31 +1029,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - -[[package]] -name = "futures" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.32" @@ -1152,17 +1045,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" -[[package]] -name = "futures-executor" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.32" @@ -1198,7 +1080,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1209,15 +1090,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "generic-array" version = "0.14.9" @@ -1228,15 +1100,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getopts" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" -dependencies = [ - "unicode-width 0.2.2", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -1259,24 +1122,11 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi 5.3.0", + "r-efi", "wasip2", "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", - "wasip2", - "wasip3", -] - [[package]] name = "gif" version = "0.14.1" @@ -1359,15 +1209,6 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - [[package]] name = "hashbrown" version = "0.16.1" @@ -1409,17 +1250,6 @@ dependencies = [ "utf8-width", ] -[[package]] -name = "html5ever" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d958c2f74b664487a2035fe1dadb032c48718a03b63f3ab0b8537db8549ed4" -dependencies = [ - "log", - "markup5ever", - "match_token", -] - [[package]] name = "http" version = "1.4.0" @@ -1633,12 +1463,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idna" version = "0.3.0" @@ -1768,7 +1592,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1827,12 +1651,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "lebe" version = "0.5.3" @@ -1892,12 +1710,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - [[package]] name = "litemap" version = "0.8.1" @@ -1950,12 +1762,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - [[package]] name = "markdown-it" version = "0.6.1" @@ -1965,7 +1771,7 @@ dependencies = [ "argparse", "const_format", "derivative", - "derive_more 0.99.20", + "derive_more", "downcast-rs", "entities", "html-escape", @@ -1979,28 +1785,6 @@ dependencies = [ "unicode-general-category", ] -[[package]] -name = "markup5ever" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fe69c934650f8f19652b3946075f0fc41ad8757dbb68f1ca14e7900ecc1c3" -dependencies = [ - "log", - "tendril", - "web_atoms", -] - -[[package]] -name = "match_token" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "matchers" version = "0.2.0" @@ -2198,7 +1982,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2312,26 +2096,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "ormc-scrape" -version = "0.0.1" -dependencies = [ - "anyhow", - "axum", - "base64", - "clap", - "futures", - "reqwest", - "scraper", - "serde", - "serde_json", - "tempfile", - "tokio", - "toolbox", - "tracing", - "url", -] - [[package]] name = "owo-colors" version = "4.2.3" @@ -2398,16 +2162,6 @@ dependencies = [ "phf_shared 0.13.1", ] -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator", - "phf_shared 0.11.3", -] - [[package]] name = "phf_generator" version = "0.11.3" @@ -2517,12 +2271,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "pretty_assertions" version = "1.4.1" @@ -2543,16 +2291,6 @@ dependencies = [ "prettytable-rs", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[package]] name = "prettytable-rs" version = "0.10.0" @@ -2764,12 +2502,6 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - [[package]] name = "rand" version = "0.8.5" @@ -3081,19 +2813,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.59.0", -] - [[package]] name = "rustls" version = "0.23.37" @@ -3162,40 +2881,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scraper" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f3a24d916e78954af99281a455168d4a9515d65eca99a18da1b813689c4ad9" -dependencies = [ - "cssparser", - "ego-tree", - "getopts", - "html5ever", - "precomputed-hash", - "selectors", - "tendril", -] - -[[package]] -name = "selectors" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5685b6ae43bfcf7d2e7dfcfb5d8e8f61b46442c902531e41a32a9a8bf0ee0fb6" -dependencies = [ - "bitflags", - "cssparser", - "derive_more 2.0.1", - "fxhash", - "log", - "new_debug_unreachable", - "phf 0.11.3", - "phf_codegen", - "precomputed-hash", - "servo_arc", - "smallvec", -] - [[package]] name = "semver" version = "1.0.27" @@ -3283,14 +2968,15 @@ dependencies = [ [[package]] name = "servable" -version = "0.0.3" +version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee682f2af773f19ca10ffafc5fe367a6a4f4a0d3b53b8724487677f46df473ae" +checksum = "4f22ed9d28b4144e9a1c91a8f227f76efcd1e1ebfd8a7911168298d6a40b97db" dependencies = [ "axum", "chrono", "image", "maud", + "mime", "rand 0.9.2", "serde", "serde_urlencoded", @@ -3301,6 +2987,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "service-assets" +version = "0.0.1" +dependencies = [ + "axum", + "grass", + "libservice", + "maud", + "mime", + "servable", + "strum", + "tokio", + "tower-http", +] + [[package]] name = "service-webpage" version = "0.0.1" @@ -3314,26 +3015,18 @@ dependencies = [ "markdown-it", "maud", "md-footnote", + "mime", "parking_lot", "reqwest", "serde", "servable", - "strum", + "service-assets", "tokio", "toml", "tower-http", "tracing", ] -[[package]] -name = "servo_arc" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "sha2" version = "0.10.9" @@ -3450,31 +3143,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "string_cache" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared 0.11.3", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" -dependencies = [ - "phf_generator", - "phf_shared 0.11.3", - "proc-macro2", - "quote", -] - [[package]] name = "strsim" version = "0.11.1" @@ -3655,30 +3323,6 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "tempfile" -version = "3.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" -dependencies = [ - "fastrand", - "getrandom 0.4.2", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "tendril" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] - [[package]] name = "term" version = "0.7.0" @@ -4231,12 +3875,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8-width" version = "0.1.7" @@ -4360,15 +3998,6 @@ dependencies = [ "wit-bindgen", ] -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen", -] - [[package]] name = "wasm-bindgen" version = "0.2.106" @@ -4427,28 +4056,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.4.2" @@ -4462,18 +4069,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-sys" version = "0.3.83" @@ -4494,18 +4089,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web_atoms" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" -dependencies = [ - "phf 0.11.3", - "phf_codegen", - "string_cache", - "string_cache_codegen", -] - [[package]] name = "webpage" version = "0.0.1" @@ -4515,6 +4098,7 @@ dependencies = [ "clap", "libservice", "serde", + "service-assets", "service-webpage", "tokio", "toolbox", @@ -4558,7 +4142,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4734,88 +4318,6 @@ name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] [[package]] name = "writeable" diff --git a/Cargo.toml b/Cargo.toml index 1da9876..f8730a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,6 @@ mutex_atomic = "deny" needless_raw_strings = "deny" str_to_string = "deny" string_add = "deny" -string_to_string = "deny" use_debug = "allow" verbose_file_reads = "deny" large_types_passed_by_value = "deny" @@ -57,6 +56,7 @@ unimplemented = "deny" unwrap_used = "warn" expect_used = "warn" type_complexity = "allow" +implicit_clone = "deny" # @@ -70,6 +70,8 @@ md-footnote = { path = "crates/lib/md-footnote" } md-dev = { path = "crates/lib/md-dev" } service-webpage = { path = "crates/service/service-webpage" } +service-assets = { path = "crates/service/service-assets" } + # # MARK: Server @@ -99,7 +101,7 @@ reqwest = { version = "0.12.28", default-features = false, features = [ "charset", "blocking", ] } -servable = { version = "0.0.3", features = ["image", "htmx-2.0.8"] } +servable = { version = "0.0.7", features = ["image", "htmx-2.0.8"] } #servable = { path = "../servable/crates/servable", features = [ # "image", # "htmx-2.0.8", @@ -151,6 +153,7 @@ image = "0.25.10" scraper = "0.24.0" futures = "0.3.32" tempfile = "3.27.0" +mime = "0.3.17" # md_* test utilities prettydiff = "0.9.0" diff --git a/crates/bin/webpage/Cargo.toml b/crates/bin/webpage/Cargo.toml index 471bc19..4b8a5c0 100644 --- a/crates/bin/webpage/Cargo.toml +++ b/crates/bin/webpage/Cargo.toml @@ -10,7 +10,9 @@ workspace = true [dependencies] toolbox = { workspace = true, features = ["cli", "loki"] } libservice = { workspace = true } + service-webpage = { workspace = true } +service-assets = { workspace = true } tracing = { workspace = true } tokio = { workspace = true } diff --git a/crates/bin/webpage/src/cmd/serve.rs b/crates/bin/webpage/src/cmd/serve.rs index 71f0fcb..14c3063 100644 --- a/crates/bin/webpage/src/cmd/serve.rs +++ b/crates/bin/webpage/src/cmd/serve.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Result}; use libservice::{Service, ServiceConnectInfo, ToService}; +use service_assets::AssetService; use service_webpage::WebpageService; use std::sync::Arc; use tracing::{error, info}; @@ -70,6 +71,11 @@ pub struct RouterState {} /// If state is none, dry-init pub async fn make_service(_state: Option>) -> Result { let service_webpage = WebpageService::new(); + let service_assets = AssetService::new(); - Ok(Service::new().merge(service_webpage).to_service().trace()) + Ok(Service::new() + .merge(service_webpage) + .nest("/assets", service_assets) + .to_service() + .trace()) } diff --git a/crates/lib/md-footnote/src/definitions.rs b/crates/lib/md-footnote/src/definitions.rs index 38b97f4..24e5f86 100644 --- a/crates/lib/md-footnote/src/definitions.rs +++ b/crates/lib/md-footnote/src/definitions.rs @@ -160,6 +160,7 @@ impl BlockRule for FootnoteDefinitionScanner { } #[cfg(test)] +#[expect(clippy::unwrap_used)] mod tests { use super::*; diff --git a/crates/lib/toolbox/src/logging.rs b/crates/lib/toolbox/src/logging.rs index 8e43cb5..5613a57 100644 --- a/crates/lib/toolbox/src/logging.rs +++ b/crates/lib/toolbox/src/logging.rs @@ -8,21 +8,16 @@ use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::Subscribe // MARK: loglevel // -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, ValueEnum)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, ValueEnum, Default)] pub enum LogLevel { Trace, Debug, + #[default] Info, Warn, Error, } -impl Default for LogLevel { - fn default() -> Self { - Self::Info - } -} - impl Display for LogLevel { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -306,19 +301,14 @@ pub enum LoggingTarget { } /// How to print logs -#[derive(Debug, Clone, Copy, Deserialize)] +#[derive(Debug, Clone, Copy, Deserialize, Default)] pub enum LoggingFormat { + #[default] Ansi, AnsiNoColor, Json, } -impl Default for LoggingFormat { - fn default() -> Self { - Self::Ansi - } -} - pub struct LoggingInitializer { pub app_name: &'static str, diff --git a/crates/service/service-assets/Cargo.toml b/crates/service/service-assets/Cargo.toml new file mode 100644 index 0000000..d9c82d9 --- /dev/null +++ b/crates/service/service-assets/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "service-assets" +version = { workspace = true } +rust-version = { workspace = true } +edition = { workspace = true } + +[lints] +workspace = true + +[dependencies] +libservice = { workspace = true } + +axum = { workspace = true } +maud = { workspace = true } +strum = { workspace = true } +tower-http = { workspace = true } +servable = { workspace = true } +mime = { workspace = true } +grass = { workspace = true } + +[dev-dependencies] +tokio = { workspace = true } diff --git a/crates/service/service-webpage/assets/fonts/fa/fa-brands-400.ttf b/crates/service/service-assets/assets/fonts/fa/fa-brands-400.ttf similarity index 100% rename from crates/service/service-webpage/assets/fonts/fa/fa-brands-400.ttf rename to crates/service/service-assets/assets/fonts/fa/fa-brands-400.ttf diff --git a/crates/service/service-webpage/assets/fonts/fa/fa-brands-400.woff2 b/crates/service/service-assets/assets/fonts/fa/fa-brands-400.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fa/fa-brands-400.woff2 rename to crates/service/service-assets/assets/fonts/fa/fa-brands-400.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fa/fa-regular-400.ttf b/crates/service/service-assets/assets/fonts/fa/fa-regular-400.ttf similarity index 100% rename from crates/service/service-webpage/assets/fonts/fa/fa-regular-400.ttf rename to crates/service/service-assets/assets/fonts/fa/fa-regular-400.ttf diff --git a/crates/service/service-webpage/assets/fonts/fa/fa-regular-400.woff2 b/crates/service/service-assets/assets/fonts/fa/fa-regular-400.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fa/fa-regular-400.woff2 rename to crates/service/service-assets/assets/fonts/fa/fa-regular-400.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fa/fa-solid-900.ttf b/crates/service/service-assets/assets/fonts/fa/fa-solid-900.ttf similarity index 100% rename from crates/service/service-webpage/assets/fonts/fa/fa-solid-900.ttf rename to crates/service/service-assets/assets/fonts/fa/fa-solid-900.ttf diff --git a/crates/service/service-webpage/assets/fonts/fa/fa-solid-900.woff2 b/crates/service/service-assets/assets/fonts/fa/fa-solid-900.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fa/fa-solid-900.woff2 rename to crates/service/service-assets/assets/fonts/fa/fa-solid-900.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fira/FiraCode-Bold.woff2 b/crates/service/service-assets/assets/fonts/fira/FiraCode-Bold.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fira/FiraCode-Bold.woff2 rename to crates/service/service-assets/assets/fonts/fira/FiraCode-Bold.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fira/FiraCode-Light.woff2 b/crates/service/service-assets/assets/fonts/fira/FiraCode-Light.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fira/FiraCode-Light.woff2 rename to crates/service/service-assets/assets/fonts/fira/FiraCode-Light.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fira/FiraCode-Medium.woff2 b/crates/service/service-assets/assets/fonts/fira/FiraCode-Medium.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fira/FiraCode-Medium.woff2 rename to crates/service/service-assets/assets/fonts/fira/FiraCode-Medium.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fira/FiraCode-Regular.woff2 b/crates/service/service-assets/assets/fonts/fira/FiraCode-Regular.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fira/FiraCode-Regular.woff2 rename to crates/service/service-assets/assets/fonts/fira/FiraCode-Regular.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fira/FiraCode-SemiBold.woff2 b/crates/service/service-assets/assets/fonts/fira/FiraCode-SemiBold.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fira/FiraCode-SemiBold.woff2 rename to crates/service/service-assets/assets/fonts/fira/FiraCode-SemiBold.woff2 diff --git a/crates/service/service-webpage/assets/fonts/fira/FiraCode-VF.woff2 b/crates/service/service-assets/assets/fonts/fira/FiraCode-VF.woff2 similarity index 100% rename from crates/service/service-webpage/assets/fonts/fira/FiraCode-VF.woff2 rename to crates/service/service-assets/assets/fonts/fira/FiraCode-VF.woff2 diff --git a/crates/service/service-webpage/assets/images/icon.png b/crates/service/service-assets/assets/icon.png similarity index 100% rename from crates/service/service-webpage/assets/images/icon.png rename to crates/service/service-assets/assets/icon.png diff --git a/crates/service/service-assets/css/fira.scss b/crates/service/service-assets/css/fira.scss new file mode 100644 index 0000000..9145cd3 --- /dev/null +++ b/crates/service/service-assets/css/fira.scss @@ -0,0 +1,28 @@ +@import "fontawesome/fontawesome"; +@import "fontawesome/brands"; +@import "fontawesome/regular"; +@import "fontawesome/solid"; + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Bold.woff2") format("woff2"); + font-weight: bold; +} + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Light.woff2") format("woff2"); + font-weight: light; +} + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Medium.woff2") format("woff2"); + font-weight: medium; +} + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Regular.woff2") format("woff2"); + font-weight: normal; +} diff --git a/crates/service/service-assets/css/fontawesome.scss b/crates/service/service-assets/css/fontawesome.scss new file mode 100644 index 0000000..9145cd3 --- /dev/null +++ b/crates/service/service-assets/css/fontawesome.scss @@ -0,0 +1,28 @@ +@import "fontawesome/fontawesome"; +@import "fontawesome/brands"; +@import "fontawesome/regular"; +@import "fontawesome/solid"; + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Bold.woff2") format("woff2"); + font-weight: bold; +} + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Light.woff2") format("woff2"); + font-weight: light; +} + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Medium.woff2") format("woff2"); + font-weight: medium; +} + +@font-face { + font-family: "Fira"; + src: url("/assets/fonts/FiraCode-Regular.woff2") format("woff2"); + font-weight: normal; +} diff --git a/css/fontawesome/_animated.scss b/crates/service/service-assets/css/fontawesome/_animated.scss similarity index 100% rename from css/fontawesome/_animated.scss rename to crates/service/service-assets/css/fontawesome/_animated.scss diff --git a/css/fontawesome/_bordered-pulled.scss b/crates/service/service-assets/css/fontawesome/_bordered-pulled.scss similarity index 100% rename from css/fontawesome/_bordered-pulled.scss rename to crates/service/service-assets/css/fontawesome/_bordered-pulled.scss diff --git a/css/fontawesome/_core.scss b/crates/service/service-assets/css/fontawesome/_core.scss similarity index 100% rename from css/fontawesome/_core.scss rename to crates/service/service-assets/css/fontawesome/_core.scss diff --git a/css/fontawesome/_fixed-width.scss b/crates/service/service-assets/css/fontawesome/_fixed-width.scss similarity index 100% rename from css/fontawesome/_fixed-width.scss rename to crates/service/service-assets/css/fontawesome/_fixed-width.scss diff --git a/css/fontawesome/_functions.scss b/crates/service/service-assets/css/fontawesome/_functions.scss similarity index 100% rename from css/fontawesome/_functions.scss rename to crates/service/service-assets/css/fontawesome/_functions.scss diff --git a/css/fontawesome/_icons.scss b/crates/service/service-assets/css/fontawesome/_icons.scss similarity index 100% rename from css/fontawesome/_icons.scss rename to crates/service/service-assets/css/fontawesome/_icons.scss diff --git a/css/fontawesome/_list.scss b/crates/service/service-assets/css/fontawesome/_list.scss similarity index 100% rename from css/fontawesome/_list.scss rename to crates/service/service-assets/css/fontawesome/_list.scss diff --git a/css/fontawesome/_mixins.scss b/crates/service/service-assets/css/fontawesome/_mixins.scss similarity index 100% rename from css/fontawesome/_mixins.scss rename to crates/service/service-assets/css/fontawesome/_mixins.scss diff --git a/css/fontawesome/_rotated-flipped.scss b/crates/service/service-assets/css/fontawesome/_rotated-flipped.scss similarity index 100% rename from css/fontawesome/_rotated-flipped.scss rename to crates/service/service-assets/css/fontawesome/_rotated-flipped.scss diff --git a/css/fontawesome/_screen-reader.scss b/crates/service/service-assets/css/fontawesome/_screen-reader.scss similarity index 100% rename from css/fontawesome/_screen-reader.scss rename to crates/service/service-assets/css/fontawesome/_screen-reader.scss diff --git a/css/fontawesome/_shims.scss b/crates/service/service-assets/css/fontawesome/_shims.scss similarity index 100% rename from css/fontawesome/_shims.scss rename to crates/service/service-assets/css/fontawesome/_shims.scss diff --git a/css/fontawesome/_sizing.scss b/crates/service/service-assets/css/fontawesome/_sizing.scss similarity index 100% rename from css/fontawesome/_sizing.scss rename to crates/service/service-assets/css/fontawesome/_sizing.scss diff --git a/css/fontawesome/_stacked.scss b/crates/service/service-assets/css/fontawesome/_stacked.scss similarity index 100% rename from css/fontawesome/_stacked.scss rename to crates/service/service-assets/css/fontawesome/_stacked.scss diff --git a/css/fontawesome/_variables.scss b/crates/service/service-assets/css/fontawesome/_variables.scss similarity index 100% rename from css/fontawesome/_variables.scss rename to crates/service/service-assets/css/fontawesome/_variables.scss diff --git a/css/fontawesome/brands.scss b/crates/service/service-assets/css/fontawesome/brands.scss similarity index 100% rename from css/fontawesome/brands.scss rename to crates/service/service-assets/css/fontawesome/brands.scss diff --git a/css/fontawesome/fontawesome.scss b/crates/service/service-assets/css/fontawesome/fontawesome.scss similarity index 100% rename from css/fontawesome/fontawesome.scss rename to crates/service/service-assets/css/fontawesome/fontawesome.scss diff --git a/css/fontawesome/regular.scss b/crates/service/service-assets/css/fontawesome/regular.scss similarity index 100% rename from css/fontawesome/regular.scss rename to crates/service/service-assets/css/fontawesome/regular.scss diff --git a/css/fontawesome/solid.scss b/crates/service/service-assets/css/fontawesome/solid.scss similarity index 100% rename from css/fontawesome/solid.scss rename to crates/service/service-assets/css/fontawesome/solid.scss diff --git a/css/fontawesome/v4-shims.scss b/crates/service/service-assets/css/fontawesome/v4-shims.scss similarity index 100% rename from css/fontawesome/v4-shims.scss rename to crates/service/service-assets/css/fontawesome/v4-shims.scss diff --git a/crates/service/service-assets/src/assets/firacode.rs b/crates/service/service-assets/src/assets/firacode.rs new file mode 100644 index 0000000..97f20ec --- /dev/null +++ b/crates/service/service-assets/src/assets/firacode.rs @@ -0,0 +1,55 @@ +use servable::{ServableWithRoute, StaticAsset}; + +pub static FONT_FIRACODE_BOLD: ServableWithRoute = ServableWithRoute::new( + || "/fonts/FiraCode-Bold.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Bold.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FIRACODE_LIGHT: ServableWithRoute = ServableWithRoute::new( + || "/fonts/FiraCode-Light.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Light.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FIRACODE_MEDIUM: ServableWithRoute = ServableWithRoute::new( + || "/fonts/FiraCode-Medium.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Medium.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FIRACODE_REGULAR: ServableWithRoute = ServableWithRoute::new( + || "/fonts/FiraCode-Regular.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Regular.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FIRACODE_SEMIBOLD: ServableWithRoute = ServableWithRoute::new( + || "/fonts/FiraCode-SemiBold.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fira/FiraCode-SemiBold.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FIRACODE_VF: ServableWithRoute = ServableWithRoute::new( + || "/fonts/FiraCode-VF.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fira/FiraCode-VF.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); diff --git a/crates/service/service-assets/src/assets/fontawesome.rs b/crates/service/service-assets/src/assets/fontawesome.rs new file mode 100644 index 0000000..4bdfa3d --- /dev/null +++ b/crates/service/service-assets/src/assets/fontawesome.rs @@ -0,0 +1,68 @@ +use std::str::FromStr; +use std::sync::LazyLock; + +use mime::Mime; +use servable::{ServableWithRoute, StaticAsset}; + +pub static FONT_FA_BRANDS_WOFF2: ServableWithRoute = ServableWithRoute::new( + || "/fonts/fa/fa-brands-400.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fa/fa-brands-400.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FA_REGULAR_WOFF2: ServableWithRoute = ServableWithRoute::new( + || "/fonts/fa/fa-regular-400.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fa/fa-regular-400.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static FONT_FA_SOLID_WOFF2: ServableWithRoute = ServableWithRoute::new( + || "/fonts/fa/fa-solid-900.woff2".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fa/fa-solid-900.woff2"), + mime: mime::FONT_WOFF2, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +#[expect(clippy::unwrap_used)] +pub static FONT_FA_BRANDS_TTF: LazyLock> = LazyLock::new(|| { + ServableWithRoute::new( + || "/fonts/fa/fa-brands-400.ttf".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fa/fa-brands-400.ttf"), + mime: Mime::from_str("font/ttf").unwrap(), + ttl: StaticAsset::DEFAULT_TTL, + }, + ) +}); + +#[expect(clippy::unwrap_used)] +pub static FONT_FA_REGULAR_TTF: LazyLock> = LazyLock::new(|| { + ServableWithRoute::new( + || "/fonts/fa/fa-regular-400.ttf".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fa/fa-regular-400.ttf"), + mime: Mime::from_str("font/ttf").unwrap(), + ttl: StaticAsset::DEFAULT_TTL, + }, + ) +}); + +#[expect(clippy::unwrap_used)] +pub static FONT_FA_SOLID_TTF: LazyLock> = LazyLock::new(|| { + ServableWithRoute::new( + || "/fonts/fa/fa-solid-900.ttf".into(), + StaticAsset { + bytes: include_bytes!("../../assets/fonts/fa/fa-solid-900.ttf"), + mime: Mime::from_str("font/ttf").unwrap(), + ttl: StaticAsset::DEFAULT_TTL, + }, + ) +}); diff --git a/crates/service/service-assets/src/assets/mod.rs b/crates/service/service-assets/src/assets/mod.rs new file mode 100644 index 0000000..de140f9 --- /dev/null +++ b/crates/service/service-assets/src/assets/mod.rs @@ -0,0 +1,44 @@ +use servable::{CACHE_BUST_STR, ServableWithRoute, StaticAsset}; + +mod firacode; +pub use firacode::*; + +mod fontawesome; +pub use fontawesome::*; + +pub static HTMX: ServableWithRoute = ServableWithRoute::new( + || "/htmx-2.0.8.js".into(), + servable::HTMX_2_0_8.with_ttl(None), +); + +pub static HTMX_JSON: ServableWithRoute = ServableWithRoute::new( + || "/htmx-json-1.19.12.js".into(), + servable::EXT_JSON_1_19_12, +); + +pub static IMG_ICON: ServableWithRoute = ServableWithRoute::new( + || "/img/icon.png".into(), + StaticAsset { + bytes: include_bytes!("../../assets/icon.png"), + mime: mime::IMAGE_PNG, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static CSS_FIRA: ServableWithRoute = ServableWithRoute::new( + || format!("/css/{}/fira.css", *CACHE_BUST_STR), + StaticAsset { + bytes: grass::include!("crates/service/service-assets/css/fira.scss").as_bytes(), + mime: mime::TEXT_CSS, + ttl: StaticAsset::DEFAULT_TTL, + }, +); + +pub static CSS_FONTAWESOME: ServableWithRoute = ServableWithRoute::new( + || format!("/css/{}/fontawesome.css", *CACHE_BUST_STR), + StaticAsset { + bytes: grass::include!("crates/service/service-assets/css/fontawesome.scss").as_bytes(), + mime: mime::TEXT_CSS, + ttl: StaticAsset::DEFAULT_TTL, + }, +); diff --git a/crates/service/service-webpage/src/components/fa.rs b/crates/service/service-assets/src/components/fa.rs similarity index 100% rename from crates/service/service-webpage/src/components/fa.rs rename to crates/service/service-assets/src/components/fa.rs diff --git a/crates/service/service-webpage/src/components/misc.rs b/crates/service/service-assets/src/components/misc.rs similarity index 100% rename from crates/service/service-webpage/src/components/misc.rs rename to crates/service/service-assets/src/components/misc.rs diff --git a/crates/service/service-assets/src/components/mod.rs b/crates/service/service-assets/src/components/mod.rs new file mode 100644 index 0000000..65ae565 --- /dev/null +++ b/crates/service/service-assets/src/components/mod.rs @@ -0,0 +1,20 @@ +pub mod fa; +pub mod misc; + +pub const LAZY_IMAGE_JS: &str = " +window.onload = function() { + var imgs = document.querySelectorAll('.img-placeholder'); + + imgs.forEach(img => { + img.style.border = 'none'; + img.style.filter = 'blur(10px)'; + img.style.transition = 'filter 0.3s'; + + var lg = new Image(); + lg.src = img.dataset.large; + lg.onload = function () { + img.src = img.dataset.large; + img.style.filter = 'blur(0px)'; + }; + }) +}"; diff --git a/crates/service/service-assets/src/lib.rs b/crates/service/service-assets/src/lib.rs new file mode 100644 index 0000000..064456b --- /dev/null +++ b/crates/service/service-assets/src/lib.rs @@ -0,0 +1,71 @@ +use axum::Router; +use libservice::ToService; +use servable::ServableRouter; +use tower_http::compression::{CompressionLayer, DefaultPredicate}; + +pub mod assets; +pub mod components; + +pub struct AssetService {} + +impl AssetService { + #[inline] + pub fn new() -> Self { + Self {} + } +} + +impl ToService for AssetService { + #[inline] + fn make_router(&self) -> Option> { + use assets::*; + let router = ServableRouter::new() + .add_page_with_route(&HTMX) + .add_page_with_route(&HTMX_JSON) + .add_page_with_route(&IMG_ICON) + // fira + .add_page_with_route(&CSS_FIRA) + .add_page_with_route(&FONT_FIRACODE_BOLD) + .add_page_with_route(&FONT_FIRACODE_LIGHT) + .add_page_with_route(&FONT_FIRACODE_MEDIUM) + .add_page_with_route(&FONT_FIRACODE_REGULAR) + .add_page_with_route(&FONT_FIRACODE_SEMIBOLD) + .add_page_with_route(&FONT_FIRACODE_VF) + // fa + .add_page_with_route(&CSS_FONTAWESOME) + .add_page_with_route(&FONT_FA_BRANDS_WOFF2) + .add_page_with_route(&FONT_FA_REGULAR_WOFF2) + .add_page_with_route(&FONT_FA_SOLID_WOFF2) + .add_page_with_route(&*FONT_FA_BRANDS_TTF) + .add_page_with_route(&*FONT_FA_REGULAR_TTF) + .add_page_with_route(&*FONT_FA_SOLID_TTF) + .into_router(); + + let compression: CompressionLayer = CompressionLayer::new() + .br(true) + .deflate(true) + .gzip(true) + .zstd(true) + .compress_when(DefaultPredicate::new()); + + Some(router.layer(compression)) + } + + #[inline] + fn service_name(&self) -> Option { + Some("assets".to_owned()) + } +} + +#[test] +#[expect(clippy::unwrap_used)] +fn server_builds_without_panic() { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { + let router = AssetService {}.make_router(); + assert!(router.is_some()) + }); +} diff --git a/crates/service/service-webpage/Cargo.toml b/crates/service/service-webpage/Cargo.toml index f8c90d9..fa088a3 100644 --- a/crates/service/service-webpage/Cargo.toml +++ b/crates/service/service-webpage/Cargo.toml @@ -9,6 +9,7 @@ workspace = true [dependencies] libservice = { workspace = true } +service-assets = { workspace = true } md-footnote = { workspace = true } @@ -18,7 +19,6 @@ axum = { workspace = true } tracing = { workspace = true } maud = { workspace = true } emojis = { workspace = true } -strum = { workspace = true } chrono = { workspace = true } parking_lot = { workspace = true } lazy_static = { workspace = true } @@ -28,3 +28,4 @@ reqwest = { workspace = true } tokio = { workspace = true } tower-http = { workspace = true } servable = { workspace = true } +mime = { workspace = true } diff --git a/css/blocks.scss b/crates/service/service-webpage/css/blocks.scss similarity index 100% rename from css/blocks.scss rename to crates/service/service-webpage/css/blocks.scss diff --git a/css/images.scss b/crates/service/service-webpage/css/images.scss similarity index 100% rename from css/images.scss rename to crates/service/service-webpage/css/images.scss diff --git a/css/main.scss b/crates/service/service-webpage/css/main.scss similarity index 68% rename from css/main.scss rename to crates/service/service-webpage/css/main.scss index c90c969..338a142 100644 --- a/css/main.scss +++ b/crates/service/service-webpage/css/main.scss @@ -3,36 +3,6 @@ @import "images"; @import "special"; -@import "fontawesome/fontawesome"; -@import "fontawesome/brands"; -@import "fontawesome/regular"; -@import "fontawesome/solid"; - - -@font-face { - font-family: "Fira"; - src: url("/assets/fonts/FiraCode-Bold.woff2") format("woff2"); - font-weight: bold; -} - -@font-face { - font-family: "Fira"; - src: url("/assets/fonts/FiraCode-Light.woff2") format("woff2"); - font-weight: light; -} - -@font-face { - font-family: "Fira"; - src: url("/assets/fonts/FiraCode-Medium.woff2") format("woff2"); - font-weight: medium; -} - -@font-face { - font-family: "Fira"; - src: url("/assets/fonts/FiraCode-Regular.woff2") format("woff2"); - font-weight: normal; -} - :root { // Misc colors --bgColor: #121212; @@ -115,3 +85,35 @@ iframe { margin: 1rem; } } + +// Loading spinner (three dots) +.htmx-indicator { + display: none; +} +.htmx-request .htmx-indicator, +.htmx-request.htmx-indicator { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 8px 0; +} + +@keyframes dot-bounce { + 0%, 80%, 100% { opacity: 0.2; transform: scale(0.8); } + 40% { opacity: 1; transform: scale(1); } +} + +.search-meta { + font-size: 1.2rem; + color: var(--grey); + margin: 0 0 1.5em 0; + text-align: left; +} + +#search-results { + margin-top: 0; +} + +#search-results ul { + margin-top: 1.5em; +} diff --git a/css/special.scss b/crates/service/service-webpage/css/special.scss similarity index 100% rename from css/special.scss rename to crates/service/service-webpage/css/special.scss diff --git a/css/text.scss b/crates/service/service-webpage/css/text.scss similarity index 100% rename from css/text.scss rename to crates/service/service-webpage/css/text.scss diff --git a/crates/service/service-webpage/src/components/md/emote.rs b/crates/service/service-webpage/src/components/md/emote.rs index 6850fd8..52313ec 100644 --- a/crates/service/service-webpage/src/components/md/emote.rs +++ b/crates/service/service-webpage/src/components/md/emote.rs @@ -1,10 +1,8 @@ -use std::str::FromStr; - use markdown_it::parser::inline::{InlineRule, InlineState}; use markdown_it::{Node, NodeValue, Renderer}; use maud::Render; - -use crate::components::fa::FAIcon; +use service_assets::components::fa::FAIcon; +use std::str::FromStr; #[derive(Debug)] pub struct InlineEmote(String); diff --git a/crates/service/service-webpage/src/components/mod.rs b/crates/service/service-webpage/src/components/mod.rs index bbc708c..8ecd5cd 100644 --- a/crates/service/service-webpage/src/components/mod.rs +++ b/crates/service/service-webpage/src/components/mod.rs @@ -1,4 +1,2 @@ -pub mod fa; pub mod mangle; pub mod md; -pub mod misc; diff --git a/crates/service/service-webpage/src/pages/betalupi.md b/crates/service/service-webpage/src/pages/betalupi.md index 40ffaba..7173cc0 100644 --- a/crates/service/service-webpage/src/pages/betalupi.md +++ b/crates/service/service-webpage/src/pages/betalupi.md @@ -31,4 +31,4 @@ A snippet of the [_Endless Sky_][es] map is below.
- + diff --git a/crates/service/service-webpage/src/pages/handouts.rs b/crates/service/service-webpage/src/pages/handouts.rs index b9e1772..1cd2b0c 100644 --- a/crates/service/service-webpage/src/pages/handouts.rs +++ b/crates/service/service-webpage/src/pages/handouts.rs @@ -9,15 +9,16 @@ use maud::{Markup, PreEscaped, html}; use parking_lot::Mutex; use serde::Deserialize; use servable::{DeviceType, HtmlPage, RenderContext}; +use service_assets::{ + assets::{CSS_FIRA, CSS_FONTAWESOME, IMG_ICON}, + components::misc::FarLink, +}; use tracing::{debug, warn}; use crate::{ - components::{ - md::{Markdown, meta_from_markdown}, - misc::FarLink, - }, + components::md::{Markdown, meta_from_markdown}, pages::{LAZY_IMAGE_JS, backlinks, footer}, - routes::{IMG_ICON, MAIN_CSS}, + routes::MAIN_CSS, }; #[derive(Debug, Deserialize)] @@ -189,13 +190,15 @@ pub static HANDOUTS: LazyLock = LazyLock::new(|| { let mut meta = meta_from_markdown(&md).unwrap().unwrap(); if meta.image.is_none() { - meta.image = Some(IMG_ICON.route().into()); + meta.image = Some(IMG_ICON.route_at("/assets")); } let html = PreEscaped(md.render()); HtmlPage::default() .with_style_linked(MAIN_CSS.route()) + .with_style_linked(CSS_FIRA.route_at("/assets")) + .with_style_linked(CSS_FONTAWESOME.route_at("/assets")) .with_script_inline(LAZY_IMAGE_JS) .with_meta(meta) .with_render(move |page, ctx| { diff --git a/crates/service/service-webpage/src/pages/index.rs b/crates/service/service-webpage/src/pages/index.rs index 65108f8..fa9eeba 100644 --- a/crates/service/service-webpage/src/pages/index.rs +++ b/crates/service/service-webpage/src/pages/index.rs @@ -1,27 +1,31 @@ use maud::{Markup, html}; use servable::{HtmlPage, PageMetadata, RenderContext}; +use service_assets::{ + assets::{CSS_FIRA, CSS_FONTAWESOME, IMG_ICON}, + components::{fa::FAIcon, misc::FarLink}, +}; use std::{pin::Pin, sync::LazyLock}; use crate::{ components::{ - fa::FAIcon, mangle::{MangledBetaEmail, MangledGoogleEmail}, md::Markdown, - misc::FarLink, }, pages::{LAZY_IMAGE_JS, footer}, - routes::{IMG_ICON, MAIN_CSS}, + routes::{IMG_COVER_SMALL, MAIN_CSS}, }; pub static INDEX: LazyLock = LazyLock::new(|| { HtmlPage::default() .with_style_linked(MAIN_CSS.route()) + .with_style_linked(CSS_FIRA.route_at("/assets")) + .with_style_linked(CSS_FONTAWESOME.route_at("/assets")) .with_script_inline(LAZY_IMAGE_JS) .with_meta(PageMetadata { title: "Betalupi: About".into(), author: Some("Mark".into()), description: None, - image: Some(IMG_ICON.route().into()), + image: Some(IMG_ICON.route_at("/assets")), }) .with_render(render) }); @@ -38,8 +42,8 @@ fn render<'a>( img class="img-placeholder" - src="/assets/img/cover-small.jpg?t=maxdim(20,20)" - data-large="/assets/img/cover-small.jpg" + src=(format!("{}?t=maxdim(20,20)", IMG_COVER_SMALL.route())) + data-large=(IMG_COVER_SMALL.route()) style="image-rendering:pixelated;float:left;margin:10px;display:block;width:25%;" {} diff --git a/crates/service/service-webpage/src/pages/mod.rs b/crates/service/service-webpage/src/pages/mod.rs index 6dc34d2..ed8d7d5 100644 --- a/crates/service/service-webpage/src/pages/mod.rs +++ b/crates/service/service-webpage/src/pages/mod.rs @@ -2,15 +2,15 @@ use chrono::TimeDelta; use maud::{Markup, PreEscaped, html}; use reqwest::StatusCode; use servable::{HtmlPage, PageMetadata, RenderContext}; +use service_assets::{ + assets::{CSS_FIRA, CSS_FONTAWESOME, IMG_ICON}, + components::{fa::FAIcon, misc::FarLink}, +}; use std::sync::LazyLock; use crate::{ - components::{ - fa::FAIcon, - md::{Markdown, meta_from_markdown}, - misc::FarLink, - }, - routes::{IMG_ICON, MAIN_CSS}, + components::md::{Markdown, meta_from_markdown}, + routes::MAIN_CSS, }; mod handouts; @@ -43,6 +43,8 @@ fn page_from_markdown(md: impl Into, default_image: Option) -> H HtmlPage::default() .with_script_inline(LAZY_IMAGE_JS) .with_style_linked(MAIN_CSS.route()) + .with_style_linked(CSS_FIRA.route_at("/assets")) + .with_style_linked(CSS_FONTAWESOME.route_at("/assets")) .with_meta(meta) .with_render(move |_page, ctx| { let html = html.clone(); @@ -162,7 +164,7 @@ pub fn footer() -> Markup { // MARK: pages // -pub const LINKS: LazyLock = LazyLock::new(|| { +pub static LINKS: LazyLock = LazyLock::new(|| { /* Dead links: @@ -170,28 +172,33 @@ pub const LINKS: LazyLock = LazyLock::new(|| { http://www.3dprintmath.com/ */ - page_from_markdown(include_str!("links.md"), Some(IMG_ICON.route().into())) + page_from_markdown(include_str!("links.md"), Some(IMG_ICON.route_at("/assets"))) }); -pub const BETALUPI: LazyLock = LazyLock::new(|| { - page_from_markdown(include_str!("betalupi.md"), Some(IMG_ICON.route().into())) +pub static BETALUPI: LazyLock = LazyLock::new(|| { + page_from_markdown( + include_str!("betalupi.md"), + Some(IMG_ICON.route_at("/assets")), + ) }); -pub const HTWAH_TYPESETTING: LazyLock = LazyLock::new(|| { +pub static HTWAH_TYPESETTING: LazyLock = LazyLock::new(|| { page_from_markdown( include_str!("htwah-typesetting.md"), - Some(IMG_ICON.route().into()), + Some(IMG_ICON.route_at("/assets")), ) }); pub static NOT_FOUND: LazyLock = LazyLock::new(|| { HtmlPage::default() .with_style_linked(MAIN_CSS.route()) + .with_style_linked(CSS_FIRA.route_at("/assets")) + .with_style_linked(CSS_FONTAWESOME.route_at("/assets")) .with_meta(PageMetadata { title: "Page not found".into(), author: None, description: None, - image: Some(IMG_ICON.route().into()), + image: Some(IMG_ICON.route_at("/assets")), }) .with_render( move |_page, _ctx| { diff --git a/crates/service/service-webpage/src/routes/mod.rs b/crates/service/service-webpage/src/routes/mod.rs index 417501e..de0f6bf 100644 --- a/crates/service/service-webpage/src/routes/mod.rs +++ b/crates/service/service-webpage/src/routes/mod.rs @@ -1,7 +1,5 @@ use axum::Router; -use servable::{ - CACHE_BUST_STR, Redirect, ServableRouter, ServableWithRoute, StaticAsset, mime::MimeType, -}; +use servable::{CACHE_BUST_STR, Redirect, ServableRouter, ServableWithRoute, StaticAsset}; use tower_http::compression::{CompressionLayer, DefaultPredicate}; use crate::pages; @@ -17,163 +15,29 @@ pub(super) fn router() -> Router<()> { build_server().into_router().layer(compression) } -pub static HTMX: ServableWithRoute = ServableWithRoute::new( - || "/assets/htmx-2.0.8.js".into(), - servable::HTMX_2_0_8.with_ttl(None), -); - -pub static HTMX_JSON: ServableWithRoute = ServableWithRoute::new( - || "/assets/htmx-json-1.19.12.js".into(), - servable::EXT_JSON_1_19_12, -); - pub static MAIN_CSS: ServableWithRoute = ServableWithRoute::new( - || format!("/assets/{}/css/main.css", *CACHE_BUST_STR), + || format!("/static/{}/css/main.css", *CACHE_BUST_STR), StaticAsset { - bytes: grass::include!("css/main.scss").as_bytes(), - mime: MimeType::Css, + bytes: grass::include!("crates/service/service-webpage/css/main.scss").as_bytes(), + mime: mime::TEXT_CSS, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static IMG_COVER_SMALL: ServableWithRoute = ServableWithRoute::new( - || "/assets/img/cover-small.jpg".into(), + || "/static/img/cover-small.jpg".into(), StaticAsset { bytes: include_bytes!("../../assets/images/cover-small.jpg"), - mime: MimeType::Jpg, + mime: mime::IMAGE_JPEG, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static IMG_BETALUPI: ServableWithRoute = ServableWithRoute::new( - || "/assets/img/betalupi.png".into(), + || "/static/img/betalupi.png".into(), StaticAsset { bytes: include_bytes!("../../assets/images/betalupi-map.png"), - mime: MimeType::Png, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static IMG_ICON: ServableWithRoute = ServableWithRoute::new( - || "/assets/img/icon.png".into(), - StaticAsset { - bytes: include_bytes!("../../assets/images/icon.png"), - mime: MimeType::Png, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -// -// MARK: fonts -// - -pub static FONT_FIRACODE_BOLD: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/FiraCode-Bold.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Bold.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FIRACODE_LIGHT: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/FiraCode-Light.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Light.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FIRACODE_MEDIUM: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/FiraCode-Medium.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Medium.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FIRACODE_REGULAR: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/FiraCode-Regular.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fira/FiraCode-Regular.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FIRACODE_SEMIBOLD: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/FiraCode-SemiBold.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fira/FiraCode-SemiBold.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FIRACODE_VF: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/FiraCode-VF.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fira/FiraCode-VF.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -// -// MARK: icons -// -pub static FONT_FA_BRANDS_WOFF2: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/fa/fa-brands-400.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fa/fa-brands-400.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FA_REGULAR_WOFF2: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/fa/fa-regular-400.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fa/fa-regular-400.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FA_SOLID_WOFF2: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/fa/fa-solid-900.woff2".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fa/fa-solid-900.woff2"), - mime: MimeType::Woff2, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FA_BRANDS_TTF: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/fa/fa-brands-400.ttf".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fa/fa-brands-400.ttf"), - mime: MimeType::Ttf, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FA_REGULAR_TTF: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/fa/fa-regular-400.ttf".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fa/fa-regular-400.ttf"), - mime: MimeType::Ttf, - ttl: StaticAsset::DEFAULT_TTL, - }, -); - -pub static FONT_FA_SOLID_TTF: ServableWithRoute = ServableWithRoute::new( - || "/assets/fonts/fa/fa-solid-900.ttf".into(), - StaticAsset { - bytes: include_bytes!("../../assets/fonts/fa/fa-solid-900.ttf"), - mime: MimeType::Ttf, + mime: mime::IMAGE_PNG, ttl: StaticAsset::DEFAULT_TTL, }, ); @@ -182,55 +46,55 @@ pub static FONT_FA_SOLID_TTF: ServableWithRoute = ServableWithRoute // MARK: htwah // pub static HTWAH_DEFINITIONS: ServableWithRoute = ServableWithRoute::new( - || "/assets/htwah/definitions.pdf".into(), + || "/static/htwah/definitions.pdf".into(), StaticAsset { bytes: include_bytes!("../../assets/htwah/definitions.pdf"), - mime: MimeType::Pdf, + mime: mime::APPLICATION_PDF, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static HTWAH_NUMBERING: ServableWithRoute = ServableWithRoute::new( - || "/assets/htwah/numbering.pdf".into(), + || "/static/htwah/numbering.pdf".into(), StaticAsset { bytes: include_bytes!("../../assets/htwah/numbering.pdf"), - mime: MimeType::Pdf, + mime: mime::APPLICATION_PDF, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static HTWAH_SOLS_A: ServableWithRoute = ServableWithRoute::new( - || "/assets/htwah/sols-a.pdf".into(), + || "/static/htwah/sols-a.pdf".into(), StaticAsset { bytes: include_bytes!("../../assets/htwah/sols-a.pdf"), - mime: MimeType::Pdf, + mime: mime::APPLICATION_PDF, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static HTWAH_SOLS_B: ServableWithRoute = ServableWithRoute::new( - || "/assets/htwah/sols-b.pdf".into(), + || "/static/htwah/sols-b.pdf".into(), StaticAsset { bytes: include_bytes!("../../assets/htwah/sols-b.pdf"), - mime: MimeType::Pdf, + mime: mime::APPLICATION_PDF, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static HTWAH_SPACING_A: ServableWithRoute = ServableWithRoute::new( - || "/assets/htwah/spacing-a.pdf".into(), + || "/static/htwah/spacing-a.pdf".into(), StaticAsset { bytes: include_bytes!("../../assets/htwah/spacing-a.pdf"), - mime: MimeType::Pdf, + mime: mime::APPLICATION_PDF, ttl: StaticAsset::DEFAULT_TTL, }, ); pub static HTWAH_SPACING_B: ServableWithRoute = ServableWithRoute::new( - || "/assets/htwah/spacing-b.pdf".into(), + || "/static/htwah/spacing-b.pdf".into(), StaticAsset { bytes: include_bytes!("../../assets/htwah/spacing-b.pdf"), - mime: MimeType::Pdf, + mime: mime::APPLICATION_PDF, ttl: StaticAsset::DEFAULT_TTL, }, ); @@ -239,39 +103,18 @@ fn build_server() -> ServableRouter { ServableRouter::new() .with_404(&pages::NOT_FOUND) .add_page("/", &pages::INDEX) - .add_page("/links", pages::LINKS) - .add_page("/whats-a-betalupi", pages::BETALUPI) + .add_page("/links", &pages::LINKS) + .add_page("/whats-a-betalupi", &pages::BETALUPI) .add_page("/handouts", &pages::HANDOUTS) .add_page("/htwah", { #[expect(clippy::unwrap_used)] Redirect::new("/handouts").unwrap() }) - .add_page("/htwah/typesetting", pages::HTWAH_TYPESETTING) - .add_page_with_route(&HTMX) - .add_page_with_route(&HTMX_JSON) + .add_page("/htwah/typesetting", &pages::HTWAH_TYPESETTING) // .add_page_with_route(&MAIN_CSS) .add_page_with_route(&IMG_COVER_SMALL) .add_page_with_route(&IMG_BETALUPI) - .add_page_with_route(&IMG_ICON) - // - // MARK: fonts - // - .add_page_with_route(&FONT_FIRACODE_BOLD) - .add_page_with_route(&FONT_FIRACODE_LIGHT) - .add_page_with_route(&FONT_FIRACODE_MEDIUM) - .add_page_with_route(&FONT_FIRACODE_REGULAR) - .add_page_with_route(&FONT_FIRACODE_SEMIBOLD) - .add_page_with_route(&FONT_FIRACODE_VF) - // - // MARK: icons - // - .add_page_with_route(&FONT_FA_BRANDS_WOFF2) - .add_page_with_route(&FONT_FA_REGULAR_WOFF2) - .add_page_with_route(&FONT_FA_SOLID_WOFF2) - .add_page_with_route(&FONT_FA_BRANDS_TTF) - .add_page_with_route(&FONT_FA_REGULAR_TTF) - .add_page_with_route(&FONT_FA_SOLID_TTF) // // MARK: htwah // @@ -284,6 +127,7 @@ fn build_server() -> ServableRouter { } #[test] +#[expect(clippy::unwrap_used)] fn server_builds_without_panic() { tokio::runtime::Builder::new_current_thread() .enable_all()