A little app to serve my photography from my personal website

markdown rendering

ericwood.org 3f266a82 8c710e98

Waiting for spindle ...
+647 -96
+545 -84
Cargo.lock
··· 3 3 version = 4 4 4 5 5 [[package]] 6 + name = "adler2" 7 + version = "2.0.1" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 10 + 11 + [[package]] 6 12 name = "aho-corasick" 7 13 version = "1.1.4" 8 14 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 24 30 checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 25 31 dependencies = [ 26 32 "libc", 33 + ] 34 + 35 + [[package]] 36 + name = "anstream" 37 + version = "0.6.21" 38 + source = "registry+https://github.com/rust-lang/crates.io-index" 39 + checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" 40 + dependencies = [ 41 + "anstyle", 42 + "anstyle-parse", 43 + "anstyle-query", 44 + "anstyle-wincon", 45 + "colorchoice", 46 + "is_terminal_polyfill", 47 + "utf8parse", 48 + ] 49 + 50 + [[package]] 51 + name = "anstyle" 52 + version = "1.0.13" 53 + source = "registry+https://github.com/rust-lang/crates.io-index" 54 + checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" 55 + 56 + [[package]] 57 + name = "anstyle-parse" 58 + version = "0.2.7" 59 + source = "registry+https://github.com/rust-lang/crates.io-index" 60 + checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 61 + dependencies = [ 62 + "utf8parse", 63 + ] 64 + 65 + [[package]] 66 + name = "anstyle-query" 67 + version = "1.1.5" 68 + source = "registry+https://github.com/rust-lang/crates.io-index" 69 + checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" 70 + dependencies = [ 71 + "windows-sys 0.61.2", 72 + ] 73 + 74 + [[package]] 75 + name = "anstyle-wincon" 76 + version = "3.0.11" 77 + source = "registry+https://github.com/rust-lang/crates.io-index" 78 + checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" 79 + dependencies = [ 80 + "anstyle", 81 + "once_cell_polyfill", 82 + "windows-sys 0.61.2", 27 83 ] 28 84 29 85 [[package]] ··· 185 241 checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" 186 242 187 243 [[package]] 244 + name = "bincode" 245 + version = "1.3.3" 246 + source = "registry+https://github.com/rust-lang/crates.io-index" 247 + checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 248 + dependencies = [ 249 + "serde", 250 + ] 251 + 252 + [[package]] 253 + name = "bit-set" 254 + version = "0.8.0" 255 + source = "registry+https://github.com/rust-lang/crates.io-index" 256 + checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" 257 + dependencies = [ 258 + "bit-vec", 259 + ] 260 + 261 + [[package]] 262 + name = "bit-vec" 263 + version = "0.8.0" 264 + source = "registry+https://github.com/rust-lang/crates.io-index" 265 + checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" 266 + 267 + [[package]] 188 268 name = "bitflags" 189 269 version = "1.3.2" 190 270 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 209 289 ] 210 290 211 291 [[package]] 292 + name = "bon" 293 + version = "3.8.1" 294 + source = "registry+https://github.com/rust-lang/crates.io-index" 295 + checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1" 296 + dependencies = [ 297 + "bon-macros", 298 + "rustversion", 299 + ] 300 + 301 + [[package]] 302 + name = "bon-macros" 303 + version = "3.8.1" 304 + source = "registry+https://github.com/rust-lang/crates.io-index" 305 + checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645" 306 + dependencies = [ 307 + "darling", 308 + "ident_case", 309 + "prettyplease", 310 + "proc-macro2", 311 + "quote", 312 + "rustversion", 313 + "syn", 314 + ] 315 + 316 + [[package]] 212 317 name = "bumpalo" 213 318 version = "3.19.0" 214 319 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 225 330 version = "1.10.1" 226 331 source = "registry+https://github.com/rust-lang/crates.io-index" 227 332 checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 333 + 334 + [[package]] 335 + name = "caseless" 336 + version = "0.2.2" 337 + source = "registry+https://github.com/rust-lang/crates.io-index" 338 + checksum = "8b6fd507454086c8edfd769ca6ada439193cdb209c7681712ef6275cccbfe5d8" 339 + dependencies = [ 340 + "unicode-normalization", 341 + ] 228 342 229 343 [[package]] 230 344 name = "cc" ··· 262 376 ] 263 377 264 378 [[package]] 379 + name = "clap" 380 + version = "4.5.53" 381 + source = "registry+https://github.com/rust-lang/crates.io-index" 382 + checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" 383 + dependencies = [ 384 + "clap_builder", 385 + "clap_derive", 386 + ] 387 + 388 + [[package]] 389 + name = "clap_builder" 390 + version = "4.5.53" 391 + source = "registry+https://github.com/rust-lang/crates.io-index" 392 + checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" 393 + dependencies = [ 394 + "anstream", 395 + "anstyle", 396 + "clap_lex", 397 + "strsim", 398 + "terminal_size", 399 + ] 400 + 401 + [[package]] 402 + name = "clap_derive" 403 + version = "4.5.49" 404 + source = "registry+https://github.com/rust-lang/crates.io-index" 405 + checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" 406 + dependencies = [ 407 + "heck", 408 + "proc-macro2", 409 + "quote", 410 + "syn", 411 + ] 412 + 413 + [[package]] 414 + name = "clap_lex" 415 + version = "0.7.6" 416 + source = "registry+https://github.com/rust-lang/crates.io-index" 417 + checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" 418 + 419 + [[package]] 420 + name = "colorchoice" 421 + version = "1.0.4" 422 + source = "registry+https://github.com/rust-lang/crates.io-index" 423 + checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 424 + 425 + [[package]] 426 + name = "comrak" 427 + version = "0.48.0" 428 + source = "registry+https://github.com/rust-lang/crates.io-index" 429 + checksum = "48bf2260aceee247c6c5639f5751dc635211895066d782d2a28fb87f2e0d5613" 430 + dependencies = [ 431 + "bon", 432 + "caseless", 433 + "clap", 434 + "emojis", 435 + "entities", 436 + "fmt2io", 437 + "jetscii", 438 + "shell-words", 439 + "syntect", 440 + "typed-arena", 441 + "unicode_categories", 442 + "xdg", 443 + ] 444 + 445 + [[package]] 265 446 name = "concurrent-queue" 266 447 version = "2.5.0" 267 448 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 317 498 checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" 318 499 319 500 [[package]] 501 + name = "crc32fast" 502 + version = "1.5.0" 503 + source = "registry+https://github.com/rust-lang/crates.io-index" 504 + checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" 505 + dependencies = [ 506 + "cfg-if", 507 + ] 508 + 509 + [[package]] 320 510 name = "crossbeam-queue" 321 511 version = "0.3.12" 322 512 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 342 532 ] 343 533 344 534 [[package]] 535 + name = "darling" 536 + version = "0.21.3" 537 + source = "registry+https://github.com/rust-lang/crates.io-index" 538 + checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" 539 + dependencies = [ 540 + "darling_core", 541 + "darling_macro", 542 + ] 543 + 544 + [[package]] 545 + name = "darling_core" 546 + version = "0.21.3" 547 + source = "registry+https://github.com/rust-lang/crates.io-index" 548 + checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" 549 + dependencies = [ 550 + "fnv", 551 + "ident_case", 552 + "proc-macro2", 553 + "quote", 554 + "strsim", 555 + "syn", 556 + ] 557 + 558 + [[package]] 559 + name = "darling_macro" 560 + version = "0.21.3" 561 + source = "registry+https://github.com/rust-lang/crates.io-index" 562 + checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" 563 + dependencies = [ 564 + "darling_core", 565 + "quote", 566 + "syn", 567 + ] 568 + 569 + [[package]] 345 570 name = "der" 346 571 version = "0.7.10" 347 572 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 350 575 "const-oid", 351 576 "pem-rfc7468", 352 577 "zeroize", 578 + ] 579 + 580 + [[package]] 581 + name = "deranged" 582 + version = "0.5.5" 583 + source = "registry+https://github.com/rust-lang/crates.io-index" 584 + checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" 585 + dependencies = [ 586 + "powerfmt", 353 587 ] 354 588 355 589 [[package]] ··· 391 625 ] 392 626 393 627 [[package]] 628 + name = "emojis" 629 + version = "0.6.4" 630 + source = "registry+https://github.com/rust-lang/crates.io-index" 631 + checksum = "99e1f1df1f181f2539bac8bf027d31ca5ffbf9e559e3f2d09413b9107b5c02f4" 632 + dependencies = [ 633 + "phf", 634 + ] 635 + 636 + [[package]] 637 + name = "entities" 638 + version = "1.0.1" 639 + source = "registry+https://github.com/rust-lang/crates.io-index" 640 + checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" 641 + 642 + [[package]] 394 643 name = "equivalent" 395 644 version = "1.0.2" 396 645 source = "registry+https://github.com/rust-lang/crates.io-index" 397 646 checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 398 647 399 648 [[package]] 649 + name = "errno" 650 + version = "0.3.14" 651 + source = "registry+https://github.com/rust-lang/crates.io-index" 652 + checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" 653 + dependencies = [ 654 + "libc", 655 + "windows-sys 0.61.2", 656 + ] 657 + 658 + [[package]] 400 659 name = "etcetera" 401 660 version = "0.8.0" 402 661 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 419 678 ] 420 679 421 680 [[package]] 681 + name = "fancy-regex" 682 + version = "0.16.2" 683 + source = "registry+https://github.com/rust-lang/crates.io-index" 684 + checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" 685 + dependencies = [ 686 + "bit-set", 687 + "regex-automata", 688 + "regex-syntax", 689 + ] 690 + 691 + [[package]] 422 692 name = "find-msvc-tools" 423 693 version = "0.1.4" 424 694 source = "registry+https://github.com/rust-lang/crates.io-index" 425 695 checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" 426 696 427 697 [[package]] 698 + name = "flate2" 699 + version = "1.1.7" 700 + source = "registry+https://github.com/rust-lang/crates.io-index" 701 + checksum = "a2152dbcb980c05735e2a651d96011320a949eb31a0c8b38b72645ce97dec676" 702 + dependencies = [ 703 + "crc32fast", 704 + "miniz_oxide", 705 + ] 706 + 707 + [[package]] 428 708 name = "flume" 429 709 version = "0.11.1" 430 710 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 434 714 "futures-sink", 435 715 "spin", 436 716 ] 717 + 718 + [[package]] 719 + name = "fmt2io" 720 + version = "1.0.0" 721 + source = "registry+https://github.com/rust-lang/crates.io-index" 722 + checksum = "6b6129284da9f7e5296cc22183a63f24300e945e297705dcc0672f7df01d62c8" 437 723 438 724 [[package]] 439 725 name = "fnv" ··· 910 1196 ] 911 1197 912 1198 [[package]] 1199 + name = "ident_case" 1200 + version = "1.0.1" 1201 + source = "registry+https://github.com/rust-lang/crates.io-index" 1202 + checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1203 + 1204 + [[package]] 913 1205 name = "idna" 914 1206 version = "1.1.0" 915 1207 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 996 1288 ] 997 1289 998 1290 [[package]] 1291 + name = "is_terminal_polyfill" 1292 + version = "1.70.2" 1293 + source = "registry+https://github.com/rust-lang/crates.io-index" 1294 + checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" 1295 + 1296 + [[package]] 999 1297 name = "itertools" 1000 1298 version = "0.14.0" 1001 1299 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1011 1309 checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 1012 1310 1013 1311 [[package]] 1312 + name = "jetscii" 1313 + version = "0.5.3" 1314 + source = "registry+https://github.com/rust-lang/crates.io-index" 1315 + checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e" 1316 + 1317 + [[package]] 1014 1318 name = "js-sys" 1015 1319 version = "0.3.81" 1016 1320 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1084 1388 ] 1085 1389 1086 1390 [[package]] 1391 + name = "linked-hash-map" 1392 + version = "0.5.6" 1393 + source = "registry+https://github.com/rust-lang/crates.io-index" 1394 + checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1395 + 1396 + [[package]] 1397 + name = "linux-raw-sys" 1398 + version = "0.11.0" 1399 + source = "registry+https://github.com/rust-lang/crates.io-index" 1400 + checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" 1401 + 1402 + [[package]] 1087 1403 name = "litemap" 1088 1404 version = "0.8.0" 1089 1405 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1111 1427 checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" 1112 1428 1113 1429 [[package]] 1114 - name = "markdown" 1115 - version = "1.0.0" 1116 - source = "registry+https://github.com/rust-lang/crates.io-index" 1117 - checksum = "a5cab8f2cadc416a82d2e783a1946388b31654d391d1c7d92cc1f03e295b1deb" 1118 - dependencies = [ 1119 - "unicode-id", 1120 - ] 1121 - 1122 - [[package]] 1123 - name = "markdown-frontmatter" 1124 - version = "0.4.0" 1125 - source = "registry+https://github.com/rust-lang/crates.io-index" 1126 - checksum = "7430fd66a1ba512543425144850284f8c821bc1e3e35cd6c13684823815d707a" 1127 - dependencies = [ 1128 - "serde", 1129 - "serde_json", 1130 - "serde_yaml", 1131 - "thiserror 2.0.17", 1132 - "toml", 1133 - ] 1134 - 1135 - [[package]] 1136 1430 name = "matchers" 1137 1431 version = "0.2.0" 1138 1432 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1207 1501 ] 1208 1502 1209 1503 [[package]] 1504 + name = "miniz_oxide" 1505 + version = "0.8.9" 1506 + source = "registry+https://github.com/rust-lang/crates.io-index" 1507 + checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" 1508 + dependencies = [ 1509 + "adler2", 1510 + "simd-adler32", 1511 + ] 1512 + 1513 + [[package]] 1210 1514 name = "mio" 1211 1515 version = "1.1.0" 1212 1516 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1269 1573 ] 1270 1574 1271 1575 [[package]] 1576 + name = "num-conv" 1577 + version = "0.1.0" 1578 + source = "registry+https://github.com/rust-lang/crates.io-index" 1579 + checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1580 + 1581 + [[package]] 1272 1582 name = "num-integer" 1273 1583 version = "0.1.46" 1274 1584 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1305 1615 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 1306 1616 1307 1617 [[package]] 1618 + name = "once_cell_polyfill" 1619 + version = "1.70.2" 1620 + source = "registry+https://github.com/rust-lang/crates.io-index" 1621 + checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" 1622 + 1623 + [[package]] 1624 + name = "onig" 1625 + version = "6.5.1" 1626 + source = "registry+https://github.com/rust-lang/crates.io-index" 1627 + checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" 1628 + dependencies = [ 1629 + "bitflags 2.9.4", 1630 + "libc", 1631 + "once_cell", 1632 + "onig_sys", 1633 + ] 1634 + 1635 + [[package]] 1636 + name = "onig_sys" 1637 + version = "69.9.1" 1638 + source = "registry+https://github.com/rust-lang/crates.io-index" 1639 + checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" 1640 + dependencies = [ 1641 + "cc", 1642 + "pkg-config", 1643 + ] 1644 + 1645 + [[package]] 1308 1646 name = "openssl-probe" 1309 1647 version = "0.1.6" 1310 1648 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1452 1790 checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" 1453 1791 1454 1792 [[package]] 1793 + name = "phf" 1794 + version = "0.11.3" 1795 + source = "registry+https://github.com/rust-lang/crates.io-index" 1796 + checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" 1797 + dependencies = [ 1798 + "phf_shared", 1799 + ] 1800 + 1801 + [[package]] 1802 + name = "phf_shared" 1803 + version = "0.11.3" 1804 + source = "registry+https://github.com/rust-lang/crates.io-index" 1805 + checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" 1806 + dependencies = [ 1807 + "siphasher", 1808 + ] 1809 + 1810 + [[package]] 1455 1811 name = "photos" 1456 1812 version = "0.1.0" 1457 1813 dependencies = [ ··· 1460 1816 "axum-extra", 1461 1817 "axum-tracing-opentelemetry", 1462 1818 "chrono", 1819 + "comrak", 1463 1820 "dotenvy", 1464 1821 "init-tracing-opentelemetry", 1465 - "markdown", 1466 - "markdown-frontmatter", 1467 1822 "minijinja", 1468 1823 "minijinja-autoreload", 1469 1824 "serde", 1470 1825 "serde_html_form", 1471 1826 "serde_valid", 1827 + "serde_yaml", 1472 1828 "sqlx", 1473 1829 "thiserror 2.0.17", 1474 1830 "tokio", ··· 1538 1894 checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 1539 1895 1540 1896 [[package]] 1897 + name = "plist" 1898 + version = "1.8.0" 1899 + source = "registry+https://github.com/rust-lang/crates.io-index" 1900 + checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" 1901 + dependencies = [ 1902 + "base64", 1903 + "indexmap", 1904 + "quick-xml", 1905 + "serde", 1906 + "time", 1907 + ] 1908 + 1909 + [[package]] 1541 1910 name = "potential_utf" 1542 1911 version = "0.1.3" 1543 1912 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1547 1916 ] 1548 1917 1549 1918 [[package]] 1919 + name = "powerfmt" 1920 + version = "0.2.0" 1921 + source = "registry+https://github.com/rust-lang/crates.io-index" 1922 + checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1923 + 1924 + [[package]] 1550 1925 name = "ppv-lite86" 1551 1926 version = "0.2.21" 1552 1927 source = "registry+https://github.com/rust-lang/crates.io-index" 1553 1928 checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 1554 1929 dependencies = [ 1555 1930 "zerocopy", 1931 + ] 1932 + 1933 + [[package]] 1934 + name = "prettyplease" 1935 + version = "0.2.37" 1936 + source = "registry+https://github.com/rust-lang/crates.io-index" 1937 + checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" 1938 + dependencies = [ 1939 + "proc-macro2", 1940 + "syn", 1556 1941 ] 1557 1942 1558 1943 [[package]] ··· 1609 1994 ] 1610 1995 1611 1996 [[package]] 1997 + name = "quick-xml" 1998 + version = "0.38.4" 1999 + source = "registry+https://github.com/rust-lang/crates.io-index" 2000 + checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" 2001 + dependencies = [ 2002 + "memchr", 2003 + ] 2004 + 2005 + [[package]] 1612 2006 name = "quinn" 1613 2007 version = "0.11.9" 1614 2008 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1856 2250 checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" 1857 2251 1858 2252 [[package]] 2253 + name = "rustix" 2254 + version = "1.1.2" 2255 + source = "registry+https://github.com/rust-lang/crates.io-index" 2256 + checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" 2257 + dependencies = [ 2258 + "bitflags 2.9.4", 2259 + "errno", 2260 + "libc", 2261 + "linux-raw-sys", 2262 + "windows-sys 0.61.2", 2263 + ] 2264 + 2265 + [[package]] 1859 2266 name = "rustls" 1860 2267 version = "0.23.35" 1861 2268 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2035 2442 ] 2036 2443 2037 2444 [[package]] 2038 - name = "serde_spanned" 2039 - version = "1.0.3" 2040 - source = "registry+https://github.com/rust-lang/crates.io-index" 2041 - checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" 2042 - dependencies = [ 2043 - "serde_core", 2044 - ] 2045 - 2046 - [[package]] 2047 2445 name = "serde_urlencoded" 2048 2446 version = "0.7.1" 2049 2447 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2145 2543 ] 2146 2544 2147 2545 [[package]] 2546 + name = "shell-words" 2547 + version = "1.1.0" 2548 + source = "registry+https://github.com/rust-lang/crates.io-index" 2549 + checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" 2550 + 2551 + [[package]] 2148 2552 name = "shlex" 2149 2553 version = "1.3.0" 2150 2554 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2161 2565 ] 2162 2566 2163 2567 [[package]] 2568 + name = "simd-adler32" 2569 + version = "0.3.7" 2570 + source = "registry+https://github.com/rust-lang/crates.io-index" 2571 + checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 2572 + 2573 + [[package]] 2574 + name = "siphasher" 2575 + version = "1.0.1" 2576 + source = "registry+https://github.com/rust-lang/crates.io-index" 2577 + checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" 2578 + 2579 + [[package]] 2164 2580 name = "slab" 2165 2581 version = "0.4.11" 2166 2582 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2453 2869 ] 2454 2870 2455 2871 [[package]] 2872 + name = "syntect" 2873 + version = "5.3.0" 2874 + source = "registry+https://github.com/rust-lang/crates.io-index" 2875 + checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925" 2876 + dependencies = [ 2877 + "bincode", 2878 + "fancy-regex", 2879 + "flate2", 2880 + "fnv", 2881 + "once_cell", 2882 + "onig", 2883 + "plist", 2884 + "regex-syntax", 2885 + "serde", 2886 + "serde_derive", 2887 + "serde_json", 2888 + "thiserror 2.0.17", 2889 + "walkdir", 2890 + "yaml-rust", 2891 + ] 2892 + 2893 + [[package]] 2894 + name = "terminal_size" 2895 + version = "0.4.3" 2896 + source = "registry+https://github.com/rust-lang/crates.io-index" 2897 + checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" 2898 + dependencies = [ 2899 + "rustix", 2900 + "windows-sys 0.60.2", 2901 + ] 2902 + 2903 + [[package]] 2456 2904 name = "thiserror" 2457 2905 version = "1.0.69" 2458 2906 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2502 2950 ] 2503 2951 2504 2952 [[package]] 2953 + name = "time" 2954 + version = "0.3.44" 2955 + source = "registry+https://github.com/rust-lang/crates.io-index" 2956 + checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" 2957 + dependencies = [ 2958 + "deranged", 2959 + "itoa", 2960 + "num-conv", 2961 + "powerfmt", 2962 + "serde", 2963 + "time-core", 2964 + "time-macros", 2965 + ] 2966 + 2967 + [[package]] 2968 + name = "time-core" 2969 + version = "0.1.6" 2970 + source = "registry+https://github.com/rust-lang/crates.io-index" 2971 + checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" 2972 + 2973 + [[package]] 2974 + name = "time-macros" 2975 + version = "0.2.24" 2976 + source = "registry+https://github.com/rust-lang/crates.io-index" 2977 + checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" 2978 + dependencies = [ 2979 + "num-conv", 2980 + "time-core", 2981 + ] 2982 + 2983 + [[package]] 2505 2984 name = "tinystr" 2506 2985 version = "0.8.1" 2507 2986 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2587 3066 ] 2588 3067 2589 3068 [[package]] 2590 - name = "toml" 2591 - version = "0.9.8" 2592 - source = "registry+https://github.com/rust-lang/crates.io-index" 2593 - checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" 2594 - dependencies = [ 2595 - "indexmap", 2596 - "serde_core", 2597 - "serde_spanned", 2598 - "toml_datetime", 2599 - "toml_parser", 2600 - "toml_writer", 2601 - "winnow", 2602 - ] 2603 - 2604 - [[package]] 2605 - name = "toml_datetime" 2606 - version = "0.7.3" 2607 - source = "registry+https://github.com/rust-lang/crates.io-index" 2608 - checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" 2609 - dependencies = [ 2610 - "serde_core", 2611 - ] 2612 - 2613 - [[package]] 2614 - name = "toml_parser" 2615 - version = "1.0.4" 2616 - source = "registry+https://github.com/rust-lang/crates.io-index" 2617 - checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" 2618 - dependencies = [ 2619 - "winnow", 2620 - ] 2621 - 2622 - [[package]] 2623 - name = "toml_writer" 2624 - version = "1.0.4" 2625 - source = "registry+https://github.com/rust-lang/crates.io-index" 2626 - checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" 2627 - 2628 - [[package]] 2629 3069 name = "tonic" 2630 3070 version = "0.14.2" 2631 3071 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2833 3273 checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2834 3274 2835 3275 [[package]] 3276 + name = "typed-arena" 3277 + version = "2.0.2" 3278 + source = "registry+https://github.com/rust-lang/crates.io-index" 3279 + checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" 3280 + 3281 + [[package]] 2836 3282 name = "typenum" 2837 3283 version = "1.19.0" 2838 3284 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2849 3295 version = "0.3.18" 2850 3296 source = "registry+https://github.com/rust-lang/crates.io-index" 2851 3297 checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" 2852 - 2853 - [[package]] 2854 - name = "unicode-id" 2855 - version = "0.3.6" 2856 - source = "registry+https://github.com/rust-lang/crates.io-index" 2857 - checksum = "70ba288e709927c043cbe476718d37be306be53fb1fafecd0dbe36d072be2580" 2858 3298 2859 3299 [[package]] 2860 3300 name = "unicode-ident" ··· 2884 3324 checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 2885 3325 2886 3326 [[package]] 3327 + name = "unicode_categories" 3328 + version = "0.1.1" 3329 + source = "registry+https://github.com/rust-lang/crates.io-index" 3330 + checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" 3331 + 3332 + [[package]] 2887 3333 name = "unsafe-libyaml" 2888 3334 version = "0.2.11" 2889 3335 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2918 3364 version = "1.0.4" 2919 3365 source = "registry+https://github.com/rust-lang/crates.io-index" 2920 3366 checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 3367 + 3368 + [[package]] 3369 + name = "utf8parse" 3370 + version = "0.2.2" 3371 + source = "registry+https://github.com/rust-lang/crates.io-index" 3372 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2921 3373 2922 3374 [[package]] 2923 3375 name = "valuable" ··· 3379 3831 checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" 3380 3832 3381 3833 [[package]] 3382 - name = "winnow" 3383 - version = "0.7.14" 3384 - source = "registry+https://github.com/rust-lang/crates.io-index" 3385 - checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" 3386 - 3387 - [[package]] 3388 3834 name = "wit-bindgen" 3389 3835 version = "0.46.0" 3390 3836 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3395 3841 version = "0.6.1" 3396 3842 source = "registry+https://github.com/rust-lang/crates.io-index" 3397 3843 checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" 3844 + 3845 + [[package]] 3846 + name = "xdg" 3847 + version = "2.5.2" 3848 + source = "registry+https://github.com/rust-lang/crates.io-index" 3849 + checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" 3850 + 3851 + [[package]] 3852 + name = "yaml-rust" 3853 + version = "0.4.5" 3854 + source = "registry+https://github.com/rust-lang/crates.io-index" 3855 + checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" 3856 + dependencies = [ 3857 + "linked-hash-map", 3858 + ] 3398 3859 3399 3860 [[package]] 3400 3861 name = "yoke"
+2 -2
Cargo.toml
··· 4 4 edition = "2024" 5 5 6 6 [dependencies] 7 - markdown = "1.0.0" 8 7 anyhow = "1.0.100" 9 8 axum = { version = "0.8.6", features = ["macros"] } 10 9 axum-extra = { version = "0.12.1", features = ["query"] } ··· 16 15 "tracing_subscriber_ext", 17 16 "metrics", 18 17 ] } 19 - markdown-frontmatter = "0.4.0" 20 18 minijinja = { version = "2.12.0", features = ["loader"] } 21 19 minijinja-autoreload = "2.12.0" 22 20 serde = "1.0.228" ··· 29 27 tower-http = { version = "0.6.6", features = ["fs", "set-header"] } 30 28 tracing = "0.1.43" 31 29 urlencoding = "2.1.3" 30 + serde_yaml = "0.9.34" 31 + comrak = "0.48.0"
+86 -3
src/blog.rs
··· 1 1 use std::{ 2 2 collections::HashMap, 3 - env, fs, 3 + env, 4 + fs::{self, File, read_to_string}, 5 + io::{BufRead, BufReader}, 4 6 path::{Path, PathBuf}, 5 7 }; 6 8 7 - pub fn get_posts() -> anyhow::Result<HashMap<String, PathBuf>> { 9 + use comrak::{markdown_to_html_with_plugins, options, plugins::syntect::SyntectAdapterBuilder}; 10 + 11 + use crate::date_time::DateTime; 12 + 13 + #[derive(serde::Deserialize, serde::Serialize)] 14 + pub struct BlogPost { 15 + pub title: Option<String>, 16 + pub published_at: Option<DateTime>, 17 + #[serde(skip_deserializing)] 18 + pub file_path: PathBuf, 19 + } 20 + 21 + pub fn get_posts() -> anyhow::Result<HashMap<String, BlogPost>> { 8 22 let path_str = env::var("BLOG_POSTS_PATH").expect("BLOG_POSTS_PATH not set"); 9 23 let root_path = Path::new(&path_str); 10 24 let mut map = HashMap::new(); ··· 25 39 let mut slug = file_name.replace("_", "-"); 26 40 slug.replace_last(".md", ""); 27 41 let path = root_path.join(file_name).clone(); 28 - map.insert(slug, path); 42 + 43 + let maybe_post = extract_frontmatter(&path)?; 44 + 45 + if let Some(mut post) = maybe_post { 46 + post.file_path = path; 47 + map.insert(slug, post); 48 + } 29 49 } 30 50 Ok(map) 31 51 } 52 + 53 + fn extract_frontmatter(path: &PathBuf) -> anyhow::Result<Option<BlogPost>> { 54 + let file = File::open(path)?; 55 + 56 + let mut yaml = String::new(); 57 + let mut lines = BufReader::new(file).lines(); 58 + 59 + let first_line = lines.next().unwrap_or(Ok("".to_string()))?; 60 + if first_line != "---" { 61 + return Ok(None); 62 + } 63 + 64 + for line in lines { 65 + if line.is_err() { 66 + break; 67 + } 68 + 69 + let line = line.unwrap_or("".to_string()); 70 + 71 + if line == "---" { 72 + break; 73 + } 74 + 75 + yaml.push_str(&format!("\n{line}")); 76 + } 77 + 78 + let post: BlogPost = serde_yaml::from_str(&yaml)?; 79 + 80 + Ok(Some(post)) 81 + } 82 + 83 + pub fn render_post(path: &PathBuf) -> anyhow::Result<String> { 84 + let md = read_to_string(path)?; 85 + let adapter = SyntectAdapterBuilder::new() 86 + .theme("base16-eighties.dark") 87 + .build(); 88 + let mut plugins = options::Plugins::default(); 89 + plugins.render.codefence_syntax_highlighter = Some(&adapter); 90 + let body = markdown_to_html_with_plugins( 91 + &md, 92 + &comrak::Options { 93 + extension: options::Extension::builder() 94 + .math_dollars(true) 95 + .multiline_block_quotes(true) 96 + .strikethrough(true) 97 + .superscript(true) 98 + .footnotes(true) 99 + .underline(true) 100 + .greentext(true) 101 + .autolink(true) 102 + .alerts(true) 103 + .table(true) 104 + .math_code(true) 105 + .maybe_front_matter_delimiter(Some("---".to_string())) 106 + .build(), 107 + parse: options::Parse::builder().build(), 108 + render: options::Render::builder().build(), 109 + }, 110 + &plugins, 111 + ); 112 + 113 + Ok(body) 114 + }
+4 -2
src/main.rs
··· 7 7 }; 8 8 use dotenvy::dotenv; 9 9 use minijinja_autoreload::AutoReloader; 10 - use std::{collections::HashMap, env, path::PathBuf, sync::Arc}; 10 + use std::{collections::HashMap, env, sync::Arc}; 11 11 use tower::ServiceBuilder; 12 12 mod app_error; 13 13 use app_error::AppError; ··· 24 24 use templates::load_templates_dyn; 25 25 use tower_http::{services::ServeDir, set_header::SetResponseHeaderLayer}; 26 26 27 + use crate::blog::BlogPost; 28 + 27 29 struct AppState { 28 30 reloader: AutoReloader, 29 31 photos_db_pool: SqlitePool, 30 - blog_slugs: HashMap<String, PathBuf>, 32 + blog_slugs: HashMap<String, BlogPost>, 31 33 } 32 34 33 35 type Response = Result<Html<String>, AppError>;
+6 -5
src/routes/blog/show.rs
··· 1 - use crate::{AppState, Response, app_error::AppError, templates::render}; 1 + use crate::{AppState, Response, app_error::AppError, blog::render_post, templates::render}; 2 2 use axum::{ 3 3 extract::{Path, State}, 4 4 response::Html, 5 5 }; 6 6 use minijinja::context; 7 - use std::{fs::read_to_string, sync::Arc}; 7 + use std::sync::Arc; 8 8 9 9 pub async fn show(Path(slug): Path<String>, State(state): State<Arc<AppState>>) -> Response { 10 - let path = state.blog_slugs.get(&slug).ok_or(AppError::NotFound)?; 11 - let md = read_to_string(path)?; 12 - let body = markdown::to_html(&md); 10 + let post = state.blog_slugs.get(&slug).ok_or(AppError::NotFound)?; 11 + let body = render_post(&post.file_path)?; 12 + 13 13 let rendered = render( 14 14 &state.reloader, 15 15 "blog/show", 16 16 context! { 17 + post, 17 18 body 18 19 }, 19 20 )?;
+4
templates/blog/show.jinja
··· 3 3 {% block title %}Blog{% endblock %} 4 4 5 5 {% block body %} 6 + <h1>{{ post.title }}</h1> 7 + <p> 8 + <time datetime="{{ post.published_at }}">{{ post.published_at }}</time> 9 + </p> 6 10 {{ body }} 7 11 {% endblock %}