Refactor, create service-assets

This commit is contained in:
2026-03-23 09:46:37 -07:00
parent 368034a177
commit 67e63019c5
61 changed files with 482 additions and 785 deletions

552
Cargo.lock generated
View File

@@ -434,12 +434,6 @@ version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "byteorder-lite" name = "byteorder-lite"
version = "0.1.0" version = "0.1.0"
@@ -738,29 +732,6 @@ dependencies = [
"typenum", "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]] [[package]]
name = "deranged" name = "deranged"
version = "0.5.8" version = "0.5.8"
@@ -805,26 +776,6 @@ dependencies = [
"syn 2.0.117", "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]] [[package]]
name = "diff" name = "diff"
version = "0.1.13" version = "0.1.13"
@@ -900,27 +851,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" 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]] [[package]]
name = "either" name = "either"
version = "1.15.0" version = "1.15.0"
@@ -999,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@@ -1028,12 +958,6 @@ dependencies = [
"regex-syntax", "regex-syntax",
] ]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "fax" name = "fax"
version = "0.2.6" version = "0.2.6"
@@ -1086,12 +1010,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.2" version = "1.2.2"
@@ -1111,31 +1029,6 @@ dependencies = [
"syn 2.0.117", "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]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.32" version = "0.3.32"
@@ -1152,17 +1045,6 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" 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]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.32" version = "0.3.32"
@@ -1198,7 +1080,6 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [ dependencies = [
"futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-macro", "futures-macro",
@@ -1209,15 +1090,6 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.9" version = "0.14.9"
@@ -1228,15 +1100,6 @@ dependencies = [
"version_check", "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]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.17" version = "0.2.17"
@@ -1259,24 +1122,11 @@ dependencies = [
"cfg-if", "cfg-if",
"js-sys", "js-sys",
"libc", "libc",
"r-efi 5.3.0", "r-efi",
"wasip2", "wasip2",
"wasm-bindgen", "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]] [[package]]
name = "gif" name = "gif"
version = "0.14.1" version = "0.14.1"
@@ -1359,15 +1209,6 @@ dependencies = [
"allocator-api2", "allocator-api2",
] ]
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.16.1" version = "0.16.1"
@@ -1409,17 +1250,6 @@ dependencies = [
"utf8-width", "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]] [[package]]
name = "http" name = "http"
version = "1.4.0" version = "1.4.0"
@@ -1633,12 +1463,6 @@ dependencies = [
"zerovec", "zerovec",
] ]
[[package]]
name = "id-arena"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.3.0" version = "0.3.0"
@@ -1768,7 +1592,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi",
"libc", "libc",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@@ -1827,12 +1651,6 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "leb128fmt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]] [[package]]
name = "lebe" name = "lebe"
version = "0.5.3" version = "0.5.3"
@@ -1892,12 +1710,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]] [[package]]
name = "litemap" name = "litemap"
version = "0.8.1" version = "0.8.1"
@@ -1950,12 +1762,6 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]] [[package]]
name = "markdown-it" name = "markdown-it"
version = "0.6.1" version = "0.6.1"
@@ -1965,7 +1771,7 @@ dependencies = [
"argparse", "argparse",
"const_format", "const_format",
"derivative", "derivative",
"derive_more 0.99.20", "derive_more",
"downcast-rs", "downcast-rs",
"entities", "entities",
"html-escape", "html-escape",
@@ -1979,28 +1785,6 @@ dependencies = [
"unicode-general-category", "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]] [[package]]
name = "matchers" name = "matchers"
version = "0.2.0" version = "0.2.0"
@@ -2198,7 +1982,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@@ -2312,26 +2096,6 @@ version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" 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]] [[package]]
name = "owo-colors" name = "owo-colors"
version = "4.2.3" version = "4.2.3"
@@ -2398,16 +2162,6 @@ dependencies = [
"phf_shared 0.13.1", "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]] [[package]]
name = "phf_generator" name = "phf_generator"
version = "0.11.3" version = "0.11.3"
@@ -2517,12 +2271,6 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "pretty_assertions" name = "pretty_assertions"
version = "1.4.1" version = "1.4.1"
@@ -2543,16 +2291,6 @@ dependencies = [
"prettytable-rs", "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]] [[package]]
name = "prettytable-rs" name = "prettytable-rs"
version = "0.10.0" version = "0.10.0"
@@ -2764,12 +2502,6 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "r-efi"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@@ -3081,19 +2813,6 @@ dependencies = [
"semver", "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]] [[package]]
name = "rustls" name = "rustls"
version = "0.23.37" version = "0.23.37"
@@ -3162,40 +2881,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 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]] [[package]]
name = "semver" name = "semver"
version = "1.0.27" version = "1.0.27"
@@ -3283,14 +2968,15 @@ dependencies = [
[[package]] [[package]]
name = "servable" name = "servable"
version = "0.0.3" version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee682f2af773f19ca10ffafc5fe367a6a4f4a0d3b53b8724487677f46df473ae" checksum = "4f22ed9d28b4144e9a1c91a8f227f76efcd1e1ebfd8a7911168298d6a40b97db"
dependencies = [ dependencies = [
"axum", "axum",
"chrono", "chrono",
"image", "image",
"maud", "maud",
"mime",
"rand 0.9.2", "rand 0.9.2",
"serde", "serde",
"serde_urlencoded", "serde_urlencoded",
@@ -3301,6 +2987,21 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "service-assets"
version = "0.0.1"
dependencies = [
"axum",
"grass",
"libservice",
"maud",
"mime",
"servable",
"strum",
"tokio",
"tower-http",
]
[[package]] [[package]]
name = "service-webpage" name = "service-webpage"
version = "0.0.1" version = "0.0.1"
@@ -3314,26 +3015,18 @@ dependencies = [
"markdown-it", "markdown-it",
"maud", "maud",
"md-footnote", "md-footnote",
"mime",
"parking_lot", "parking_lot",
"reqwest", "reqwest",
"serde", "serde",
"servable", "servable",
"strum", "service-assets",
"tokio", "tokio",
"toml", "toml",
"tower-http", "tower-http",
"tracing", "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]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.9" version = "0.10.9"
@@ -3450,31 +3143,6 @@ dependencies = [
"windows-sys 0.59.0", "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]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
@@ -3655,30 +3323,6 @@ dependencies = [
"yaml-rust", "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]] [[package]]
name = "term" name = "term"
version = "0.7.0" version = "0.7.0"
@@ -4231,12 +3875,6 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]] [[package]]
name = "utf8-width" name = "utf8-width"
version = "0.1.7" version = "0.1.7"
@@ -4360,15 +3998,6 @@ dependencies = [
"wit-bindgen", "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]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.106" version = "0.2.106"
@@ -4427,28 +4056,6 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "wasm-streams" name = "wasm-streams"
version = "0.4.2" version = "0.4.2"
@@ -4462,18 +4069,6 @@ dependencies = [
"web-sys", "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]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.83" version = "0.3.83"
@@ -4494,18 +4089,6 @@ dependencies = [
"wasm-bindgen", "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]] [[package]]
name = "webpage" name = "webpage"
version = "0.0.1" version = "0.0.1"
@@ -4515,6 +4098,7 @@ dependencies = [
"clap", "clap",
"libservice", "libservice",
"serde", "serde",
"service-assets",
"service-webpage", "service-webpage",
"tokio", "tokio",
"toolbox", "toolbox",
@@ -4558,7 +4142,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@@ -4734,88 +4318,6 @@ name = "wit-bindgen"
version = "0.51.0" version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" 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]] [[package]]
name = "writeable" name = "writeable"

View File

@@ -40,7 +40,6 @@ mutex_atomic = "deny"
needless_raw_strings = "deny" needless_raw_strings = "deny"
str_to_string = "deny" str_to_string = "deny"
string_add = "deny" string_add = "deny"
string_to_string = "deny"
use_debug = "allow" use_debug = "allow"
verbose_file_reads = "deny" verbose_file_reads = "deny"
large_types_passed_by_value = "deny" large_types_passed_by_value = "deny"
@@ -57,6 +56,7 @@ unimplemented = "deny"
unwrap_used = "warn" unwrap_used = "warn"
expect_used = "warn" expect_used = "warn"
type_complexity = "allow" type_complexity = "allow"
implicit_clone = "deny"
# #
@@ -70,6 +70,8 @@ md-footnote = { path = "crates/lib/md-footnote" }
md-dev = { path = "crates/lib/md-dev" } md-dev = { path = "crates/lib/md-dev" }
service-webpage = { path = "crates/service/service-webpage" } service-webpage = { path = "crates/service/service-webpage" }
service-assets = { path = "crates/service/service-assets" }
# #
# MARK: Server # MARK: Server
@@ -99,7 +101,7 @@ reqwest = { version = "0.12.28", default-features = false, features = [
"charset", "charset",
"blocking", "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 = [ #servable = { path = "../servable/crates/servable", features = [
# "image", # "image",
# "htmx-2.0.8", # "htmx-2.0.8",
@@ -151,6 +153,7 @@ image = "0.25.10"
scraper = "0.24.0" scraper = "0.24.0"
futures = "0.3.32" futures = "0.3.32"
tempfile = "3.27.0" tempfile = "3.27.0"
mime = "0.3.17"
# md_* test utilities # md_* test utilities
prettydiff = "0.9.0" prettydiff = "0.9.0"

View File

@@ -10,7 +10,9 @@ workspace = true
[dependencies] [dependencies]
toolbox = { workspace = true, features = ["cli", "loki"] } toolbox = { workspace = true, features = ["cli", "loki"] }
libservice = { workspace = true } libservice = { workspace = true }
service-webpage = { workspace = true } service-webpage = { workspace = true }
service-assets = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }

View File

@@ -1,5 +1,6 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use libservice::{Service, ServiceConnectInfo, ToService}; use libservice::{Service, ServiceConnectInfo, ToService};
use service_assets::AssetService;
use service_webpage::WebpageService; use service_webpage::WebpageService;
use std::sync::Arc; use std::sync::Arc;
use tracing::{error, info}; use tracing::{error, info};
@@ -70,6 +71,11 @@ pub struct RouterState {}
/// If state is none, dry-init /// If state is none, dry-init
pub async fn make_service(_state: Option<Arc<RouterState>>) -> Result<impl ToService> { pub async fn make_service(_state: Option<Arc<RouterState>>) -> Result<impl ToService> {
let service_webpage = WebpageService::new(); 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())
} }

View File

@@ -160,6 +160,7 @@ impl BlockRule for FootnoteDefinitionScanner {
} }
#[cfg(test)] #[cfg(test)]
#[expect(clippy::unwrap_used)]
mod tests { mod tests {
use super::*; use super::*;

View File

@@ -8,21 +8,16 @@ use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::Subscribe
// MARK: loglevel // MARK: loglevel
// //
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, ValueEnum)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, ValueEnum, Default)]
pub enum LogLevel { pub enum LogLevel {
Trace, Trace,
Debug, Debug,
#[default]
Info, Info,
Warn, Warn,
Error, Error,
} }
impl Default for LogLevel {
fn default() -> Self {
Self::Info
}
}
impl Display for LogLevel { impl Display for LogLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
@@ -306,19 +301,14 @@ pub enum LoggingTarget {
} }
/// How to print logs /// How to print logs
#[derive(Debug, Clone, Copy, Deserialize)] #[derive(Debug, Clone, Copy, Deserialize, Default)]
pub enum LoggingFormat { pub enum LoggingFormat {
#[default]
Ansi, Ansi,
AnsiNoColor, AnsiNoColor,
Json, Json,
} }
impl Default for LoggingFormat {
fn default() -> Self {
Self::Ansi
}
}
pub struct LoggingInitializer { pub struct LoggingInitializer {
pub app_name: &'static str, pub app_name: &'static str,

View File

@@ -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 }

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,55 @@
use servable::{ServableWithRoute, StaticAsset};
pub static FONT_FIRACODE_BOLD: ServableWithRoute<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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,
},
);

View File

@@ -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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<ServableWithRoute<StaticAsset>> = 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<ServableWithRoute<StaticAsset>> = 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<ServableWithRoute<StaticAsset>> = 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,
},
)
});

View File

@@ -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<StaticAsset> = ServableWithRoute::new(
|| "/htmx-2.0.8.js".into(),
servable::HTMX_2_0_8.with_ttl(None),
);
pub static HTMX_JSON: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/htmx-json-1.19.12.js".into(),
servable::EXT_JSON_1_19_12,
);
pub static IMG_ICON: ServableWithRoute<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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,
},
);

View File

@@ -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)';
};
})
}";

View File

@@ -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<Router<()>> {
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<String> {
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())
});
}

View File

@@ -9,6 +9,7 @@ workspace = true
[dependencies] [dependencies]
libservice = { workspace = true } libservice = { workspace = true }
service-assets = { workspace = true }
md-footnote = { workspace = true } md-footnote = { workspace = true }
@@ -18,7 +19,6 @@ axum = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
maud = { workspace = true } maud = { workspace = true }
emojis = { workspace = true } emojis = { workspace = true }
strum = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
lazy_static = { workspace = true } lazy_static = { workspace = true }
@@ -28,3 +28,4 @@ reqwest = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tower-http = { workspace = true } tower-http = { workspace = true }
servable = { workspace = true } servable = { workspace = true }
mime = { workspace = true }

View File

@@ -3,36 +3,6 @@
@import "images"; @import "images";
@import "special"; @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 { :root {
// Misc colors // Misc colors
--bgColor: #121212; --bgColor: #121212;
@@ -115,3 +85,35 @@ iframe {
margin: 1rem; 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;
}

View File

@@ -1,10 +1,8 @@
use std::str::FromStr;
use markdown_it::parser::inline::{InlineRule, InlineState}; use markdown_it::parser::inline::{InlineRule, InlineState};
use markdown_it::{Node, NodeValue, Renderer}; use markdown_it::{Node, NodeValue, Renderer};
use maud::Render; use maud::Render;
use service_assets::components::fa::FAIcon;
use crate::components::fa::FAIcon; use std::str::FromStr;
#[derive(Debug)] #[derive(Debug)]
pub struct InlineEmote(String); pub struct InlineEmote(String);

View File

@@ -1,4 +1,2 @@
pub mod fa;
pub mod mangle; pub mod mangle;
pub mod md; pub mod md;
pub mod misc;

View File

@@ -31,4 +31,4 @@ A snippet of the [_Endless Sky_][es] map is below.
<br/> <br/>
<img class="img-placeholder" src="/assets/img/betalupi.png?t=maxdim(50,50)" data-large="/assets/img/betalupi.png" style="width:100%;height=10rem;"></img> <img class="img-placeholder" src="/static/img/betalupi.png?t=maxdim(50,50)" data-large="/static/img/betalupi.png" style="width:100%;height=10rem;"></img>

View File

@@ -9,15 +9,16 @@ use maud::{Markup, PreEscaped, html};
use parking_lot::Mutex; use parking_lot::Mutex;
use serde::Deserialize; use serde::Deserialize;
use servable::{DeviceType, HtmlPage, RenderContext}; use servable::{DeviceType, HtmlPage, RenderContext};
use service_assets::{
assets::{CSS_FIRA, CSS_FONTAWESOME, IMG_ICON},
components::misc::FarLink,
};
use tracing::{debug, warn}; use tracing::{debug, warn};
use crate::{ use crate::{
components::{ components::md::{Markdown, meta_from_markdown},
md::{Markdown, meta_from_markdown},
misc::FarLink,
},
pages::{LAZY_IMAGE_JS, backlinks, footer}, pages::{LAZY_IMAGE_JS, backlinks, footer},
routes::{IMG_ICON, MAIN_CSS}, routes::MAIN_CSS,
}; };
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@@ -189,13 +190,15 @@ pub static HANDOUTS: LazyLock<HtmlPage> = LazyLock::new(|| {
let mut meta = meta_from_markdown(&md).unwrap().unwrap(); let mut meta = meta_from_markdown(&md).unwrap().unwrap();
if meta.image.is_none() { 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()); let html = PreEscaped(md.render());
HtmlPage::default() HtmlPage::default()
.with_style_linked(MAIN_CSS.route()) .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_script_inline(LAZY_IMAGE_JS)
.with_meta(meta) .with_meta(meta)
.with_render(move |page, ctx| { .with_render(move |page, ctx| {

View File

@@ -1,27 +1,31 @@
use maud::{Markup, html}; use maud::{Markup, html};
use servable::{HtmlPage, PageMetadata, RenderContext}; 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 std::{pin::Pin, sync::LazyLock};
use crate::{ use crate::{
components::{ components::{
fa::FAIcon,
mangle::{MangledBetaEmail, MangledGoogleEmail}, mangle::{MangledBetaEmail, MangledGoogleEmail},
md::Markdown, md::Markdown,
misc::FarLink,
}, },
pages::{LAZY_IMAGE_JS, footer}, pages::{LAZY_IMAGE_JS, footer},
routes::{IMG_ICON, MAIN_CSS}, routes::{IMG_COVER_SMALL, MAIN_CSS},
}; };
pub static INDEX: LazyLock<HtmlPage> = LazyLock::new(|| { pub static INDEX: LazyLock<HtmlPage> = LazyLock::new(|| {
HtmlPage::default() HtmlPage::default()
.with_style_linked(MAIN_CSS.route()) .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_script_inline(LAZY_IMAGE_JS)
.with_meta(PageMetadata { .with_meta(PageMetadata {
title: "Betalupi: About".into(), title: "Betalupi: About".into(),
author: Some("Mark".into()), author: Some("Mark".into()),
description: None, description: None,
image: Some(IMG_ICON.route().into()), image: Some(IMG_ICON.route_at("/assets")),
}) })
.with_render(render) .with_render(render)
}); });
@@ -38,8 +42,8 @@ fn render<'a>(
img img
class="img-placeholder" class="img-placeholder"
src="/assets/img/cover-small.jpg?t=maxdim(20,20)" src=(format!("{}?t=maxdim(20,20)", IMG_COVER_SMALL.route()))
data-large="/assets/img/cover-small.jpg" data-large=(IMG_COVER_SMALL.route())
style="image-rendering:pixelated;float:left;margin:10px;display:block;width:25%;" style="image-rendering:pixelated;float:left;margin:10px;display:block;width:25%;"
{} {}

View File

@@ -2,15 +2,15 @@ use chrono::TimeDelta;
use maud::{Markup, PreEscaped, html}; use maud::{Markup, PreEscaped, html};
use reqwest::StatusCode; use reqwest::StatusCode;
use servable::{HtmlPage, PageMetadata, RenderContext}; 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 std::sync::LazyLock;
use crate::{ use crate::{
components::{ components::md::{Markdown, meta_from_markdown},
fa::FAIcon, routes::MAIN_CSS,
md::{Markdown, meta_from_markdown},
misc::FarLink,
},
routes::{IMG_ICON, MAIN_CSS},
}; };
mod handouts; mod handouts;
@@ -43,6 +43,8 @@ fn page_from_markdown(md: impl Into<String>, default_image: Option<String>) -> H
HtmlPage::default() HtmlPage::default()
.with_script_inline(LAZY_IMAGE_JS) .with_script_inline(LAZY_IMAGE_JS)
.with_style_linked(MAIN_CSS.route()) .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_meta(meta)
.with_render(move |_page, ctx| { .with_render(move |_page, ctx| {
let html = html.clone(); let html = html.clone();
@@ -162,7 +164,7 @@ pub fn footer() -> Markup {
// MARK: pages // MARK: pages
// //
pub const LINKS: LazyLock<HtmlPage> = LazyLock::new(|| { pub static LINKS: LazyLock<HtmlPage> = LazyLock::new(|| {
/* /*
Dead links: Dead links:
@@ -170,28 +172,33 @@ pub const LINKS: LazyLock<HtmlPage> = LazyLock::new(|| {
http://www.3dprintmath.com/ 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<HtmlPage> = LazyLock::new(|| { pub static BETALUPI: LazyLock<HtmlPage> = LazyLock::new(|| {
page_from_markdown(include_str!("betalupi.md"), Some(IMG_ICON.route().into())) page_from_markdown(
include_str!("betalupi.md"),
Some(IMG_ICON.route_at("/assets")),
)
}); });
pub const HTWAH_TYPESETTING: LazyLock<HtmlPage> = LazyLock::new(|| { pub static HTWAH_TYPESETTING: LazyLock<HtmlPage> = LazyLock::new(|| {
page_from_markdown( page_from_markdown(
include_str!("htwah-typesetting.md"), include_str!("htwah-typesetting.md"),
Some(IMG_ICON.route().into()), Some(IMG_ICON.route_at("/assets")),
) )
}); });
pub static NOT_FOUND: LazyLock<HtmlPage> = LazyLock::new(|| { pub static NOT_FOUND: LazyLock<HtmlPage> = LazyLock::new(|| {
HtmlPage::default() HtmlPage::default()
.with_style_linked(MAIN_CSS.route()) .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 { .with_meta(PageMetadata {
title: "Page not found".into(), title: "Page not found".into(),
author: None, author: None,
description: None, description: None,
image: Some(IMG_ICON.route().into()), image: Some(IMG_ICON.route_at("/assets")),
}) })
.with_render( .with_render(
move |_page, _ctx| { move |_page, _ctx| {

View File

@@ -1,7 +1,5 @@
use axum::Router; use axum::Router;
use servable::{ use servable::{CACHE_BUST_STR, Redirect, ServableRouter, ServableWithRoute, StaticAsset};
CACHE_BUST_STR, Redirect, ServableRouter, ServableWithRoute, StaticAsset, mime::MimeType,
};
use tower_http::compression::{CompressionLayer, DefaultPredicate}; use tower_http::compression::{CompressionLayer, DefaultPredicate};
use crate::pages; use crate::pages;
@@ -17,163 +15,29 @@ pub(super) fn router() -> Router<()> {
build_server().into_router().layer(compression) build_server().into_router().layer(compression)
} }
pub static HTMX: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htmx-2.0.8.js".into(),
servable::HTMX_2_0_8.with_ttl(None),
);
pub static HTMX_JSON: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htmx-json-1.19.12.js".into(),
servable::EXT_JSON_1_19_12,
);
pub static MAIN_CSS: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static MAIN_CSS: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| format!("/assets/{}/css/main.css", *CACHE_BUST_STR), || format!("/static/{}/css/main.css", *CACHE_BUST_STR),
StaticAsset { StaticAsset {
bytes: grass::include!("css/main.scss").as_bytes(), bytes: grass::include!("crates/service/service-webpage/css/main.scss").as_bytes(),
mime: MimeType::Css, mime: mime::TEXT_CSS,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static IMG_COVER_SMALL: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static IMG_COVER_SMALL: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/img/cover-small.jpg".into(), || "/static/img/cover-small.jpg".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/images/cover-small.jpg"), bytes: include_bytes!("../../assets/images/cover-small.jpg"),
mime: MimeType::Jpg, mime: mime::IMAGE_JPEG,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static IMG_BETALUPI: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static IMG_BETALUPI: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/img/betalupi.png".into(), || "/static/img/betalupi.png".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/images/betalupi-map.png"), bytes: include_bytes!("../../assets/images/betalupi-map.png"),
mime: MimeType::Png, mime: mime::IMAGE_PNG,
ttl: StaticAsset::DEFAULT_TTL,
},
);
pub static IMG_ICON: ServableWithRoute<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = 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<StaticAsset> = ServableWithRoute::new(
|| "/assets/fonts/fa/fa-solid-900.ttf".into(),
StaticAsset {
bytes: include_bytes!("../../assets/fonts/fa/fa-solid-900.ttf"),
mime: MimeType::Ttf,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
@@ -182,55 +46,55 @@ pub static FONT_FA_SOLID_TTF: ServableWithRoute<StaticAsset> = ServableWithRoute
// MARK: htwah // MARK: htwah
// //
pub static HTWAH_DEFINITIONS: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static HTWAH_DEFINITIONS: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htwah/definitions.pdf".into(), || "/static/htwah/definitions.pdf".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/htwah/definitions.pdf"), bytes: include_bytes!("../../assets/htwah/definitions.pdf"),
mime: MimeType::Pdf, mime: mime::APPLICATION_PDF,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static HTWAH_NUMBERING: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static HTWAH_NUMBERING: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htwah/numbering.pdf".into(), || "/static/htwah/numbering.pdf".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/htwah/numbering.pdf"), bytes: include_bytes!("../../assets/htwah/numbering.pdf"),
mime: MimeType::Pdf, mime: mime::APPLICATION_PDF,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static HTWAH_SOLS_A: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static HTWAH_SOLS_A: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htwah/sols-a.pdf".into(), || "/static/htwah/sols-a.pdf".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/htwah/sols-a.pdf"), bytes: include_bytes!("../../assets/htwah/sols-a.pdf"),
mime: MimeType::Pdf, mime: mime::APPLICATION_PDF,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static HTWAH_SOLS_B: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static HTWAH_SOLS_B: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htwah/sols-b.pdf".into(), || "/static/htwah/sols-b.pdf".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/htwah/sols-b.pdf"), bytes: include_bytes!("../../assets/htwah/sols-b.pdf"),
mime: MimeType::Pdf, mime: mime::APPLICATION_PDF,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static HTWAH_SPACING_A: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static HTWAH_SPACING_A: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htwah/spacing-a.pdf".into(), || "/static/htwah/spacing-a.pdf".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/htwah/spacing-a.pdf"), bytes: include_bytes!("../../assets/htwah/spacing-a.pdf"),
mime: MimeType::Pdf, mime: mime::APPLICATION_PDF,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
pub static HTWAH_SPACING_B: ServableWithRoute<StaticAsset> = ServableWithRoute::new( pub static HTWAH_SPACING_B: ServableWithRoute<StaticAsset> = ServableWithRoute::new(
|| "/assets/htwah/spacing-b.pdf".into(), || "/static/htwah/spacing-b.pdf".into(),
StaticAsset { StaticAsset {
bytes: include_bytes!("../../assets/htwah/spacing-b.pdf"), bytes: include_bytes!("../../assets/htwah/spacing-b.pdf"),
mime: MimeType::Pdf, mime: mime::APPLICATION_PDF,
ttl: StaticAsset::DEFAULT_TTL, ttl: StaticAsset::DEFAULT_TTL,
}, },
); );
@@ -239,39 +103,18 @@ fn build_server() -> ServableRouter {
ServableRouter::new() ServableRouter::new()
.with_404(&pages::NOT_FOUND) .with_404(&pages::NOT_FOUND)
.add_page("/", &pages::INDEX) .add_page("/", &pages::INDEX)
.add_page("/links", pages::LINKS) .add_page("/links", &pages::LINKS)
.add_page("/whats-a-betalupi", pages::BETALUPI) .add_page("/whats-a-betalupi", &pages::BETALUPI)
.add_page("/handouts", &pages::HANDOUTS) .add_page("/handouts", &pages::HANDOUTS)
.add_page("/htwah", { .add_page("/htwah", {
#[expect(clippy::unwrap_used)] #[expect(clippy::unwrap_used)]
Redirect::new("/handouts").unwrap() Redirect::new("/handouts").unwrap()
}) })
.add_page("/htwah/typesetting", pages::HTWAH_TYPESETTING) .add_page("/htwah/typesetting", &pages::HTWAH_TYPESETTING)
.add_page_with_route(&HTMX)
.add_page_with_route(&HTMX_JSON)
// //
.add_page_with_route(&MAIN_CSS) .add_page_with_route(&MAIN_CSS)
.add_page_with_route(&IMG_COVER_SMALL) .add_page_with_route(&IMG_COVER_SMALL)
.add_page_with_route(&IMG_BETALUPI) .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 // MARK: htwah
// //
@@ -284,6 +127,7 @@ fn build_server() -> ServableRouter {
} }
#[test] #[test]
#[expect(clippy::unwrap_used)]
fn server_builds_without_panic() { fn server_builds_without_panic() {
tokio::runtime::Builder::new_current_thread() tokio::runtime::Builder::new_current_thread()
.enable_all() .enable_all()