diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c1e2c64 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/Cargo.lock b/Cargo.lock index c7d3057..bd481b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,155 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-priority-channel" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c21678992e1b21bebfe2bc53ab5f5f68c106eddab31b24e0bb06e9b715a86640" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-recursion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-take" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ab6b55fe97976e46f91ddbed8d147d966475dc29b2032757ba47e02376fbc3" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "block-buffer" version = "0.10.4" @@ -17,12 +160,60 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bstr" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "btoi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" +dependencies = [ + "num-traits", +] + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clearscreen" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f3f22f1a586604e62efd23f78218f3ccdecf7a33c4500db2d37d85a24fe994" +dependencies = [ + "nix", + "terminfo", + "thiserror", + "which", + "winapi", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -33,6 +224,27 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "command-group" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5080df6b0f0ecb76cab30808f00d937ba725cebe266a3da8cd89dff92f2a9916" +dependencies = [ + "async-trait", + "nix", + "tokio", + "winapi", +] + +[[package]] +name = "copy_dir" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "543d1dd138ef086e2ff05e3a48cf9da045da2033d16f8538fd76b86cd49b2ca3" +dependencies = [ + "walkdir", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -42,6 +254,25 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -52,6 +283,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" + [[package]] name = "digest" version = "0.10.7" @@ -62,6 +299,202 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "filetime" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "windows-sys 0.48.0", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -72,6 +505,253 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "gix-actor" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848efa0f1210cea8638f95691c82a46f98a74b9e3524f01d4955ebc25a8f84f3" +dependencies = [ + "bstr", + "btoi", + "gix-date", + "itoa", + "nom", + "thiserror", +] + +[[package]] +name = "gix-config" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d252a0eddb6df74600d3d8872dc9fe98835a7da43110411d705b682f49d4ac1" +dependencies = [ + "bstr", + "gix-config-value", + "gix-features", + "gix-glob", + "gix-path", + "gix-ref", + "gix-sec", + "log", + "memchr", + "nom", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-config-value" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e874f41437441c02991dcea76990b9058fadfc54b02ab4dd06ab2218af43897" +dependencies = [ + "bitflags 2.4.0", + "bstr", + "gix-path", + "libc", + "thiserror", +] + +[[package]] +name = "gix-date" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc164145670e9130a60a21670d9b6f0f4f8de04e5dd256c51fa5a0340c625902" +dependencies = [ + "bstr", + "itoa", + "thiserror", + "time", +] + +[[package]] +name = "gix-features" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf69b0f5c701cc3ae22d3204b671907668f6437ca88862d355eaf9bc47a4f897" +dependencies = [ + "gix-hash", + "libc", + "sha1_smol", + "walkdir", +] + +[[package]] +name = "gix-fs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b37a1832f691fdc09910bd267f9a2e413737c1f9ec68c6e31f9e802616278a9" +dependencies = [ + "gix-features", +] + +[[package]] +name = "gix-glob" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07c98204529ac3f24b34754540a852593d2a4c7349008df389240266627a72a" +dependencies = [ + "bitflags 2.4.0", + "bstr", + "gix-features", + "gix-path", +] + +[[package]] +name = "gix-hash" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b422ff2ad9a0628baaad6da468cf05385bf3f5ab495ad5a33cce99b9f41092f" +dependencies = [ + "hex", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c693d7f05730fa74a7c467150adc7cea393518410c65f0672f80226b8111555" +dependencies = [ + "gix-tempfile", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d96bd620fd08accdd37f70b2183cfa0b001b4f1c6ade8b7f6e15cb3d9e261ce" +dependencies = [ + "bstr", + "btoi", + "gix-actor", + "gix-features", + "gix-hash", + "gix-validate", + "hex", + "itoa", + "nom", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-path" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18609c8cbec8508ea97c64938c33cd305b75dfc04a78d0c3b78b8b3fd618a77c" +dependencies = [ + "bstr", + "gix-trace", + "home", + "once_cell", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e03989e9d49954368e1b526578230fc7189d1634acdfbe79e9ba1de717e15d5" +dependencies = [ + "gix-actor", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-validate", + "memmap2", + "nom", + "thiserror", +] + +[[package]] +name = "gix-sec" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9615cbd6b456898aeb942cd75e5810c382fbfc48dbbff2fa23ebd2d33dcbe9c7" +dependencies = [ + "bitflags 2.4.0", + "gix-path", + "libc", + "windows", +] + +[[package]] +name = "gix-tempfile" +version = "5.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71a0d32f34e71e86586124225caefd78dabc605d0486de580d717653addf182" +dependencies = [ + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "tempfile", +] + +[[package]] +name = "gix-trace" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836" + +[[package]] +name = "gix-utils" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f" +dependencies = [ + "fastrand", +] + +[[package]] +name = "gix-validate" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9b3737b2cef3dcd014633485f0034b0f1a931ee54aeb7d8f87f177f3c89040" +dependencies = [ + "bstr", + "thiserror", +] + +[[package]] +name = "globset" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "handlebars" version = "4.3.7" @@ -86,36 +766,430 @@ dependencies = [ "thiserror", ] +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "ignore-files" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a4d73056a8d335492938cabeef794f38968ef43e6db9bc946638cfd6281003b" +dependencies = [ + "dunce", + "futures", + "gix-config", + "ignore", + "miette", + "project-origins", + "radix_trie", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "matchit" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" + [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", + "pin-utils", + "static_assertions", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normalize-path" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5438dd2b2ff4c6df6e1ce22d825ed2fa93ee2922235cc45186991717f0a892d" + +[[package]] +name = "notify" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" +dependencies = [ + "bitflags 1.3.2", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets 0.48.3", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + [[package]] name = "pest" version = "2.7.2" @@ -160,6 +1234,76 @@ dependencies = [ "sha2", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro2" version = "1.0.66" @@ -169,13 +1313,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "project-origins" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629e0d57f265ca8238345cb616eea8847b8ecb86b5d97d155be2c8963a314379" +dependencies = [ + "futures", + "tokio", + "tokio-stream", +] + [[package]] name = "pulldown-cmark" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" dependencies = [ - "bitflags", + "bitflags 1.3.2", "memchr", "unicase", ] @@ -189,17 +1344,154 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "serde_json" @@ -212,6 +1504,34 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "sha2" version = "0.10.7" @@ -223,6 +1543,62 @@ dependencies = [ "digest", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "2.0.29" @@ -234,6 +1610,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -243,6 +1638,19 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminfo" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f" +dependencies = [ + "dirs", + "fnv", + "nom", + "phf", + "phf_codegen", +] + [[package]] name = "thiserror" version = "1.0.47" @@ -263,25 +1671,231 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +dependencies = [ + "deranged", + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +dependencies = [ + "time-core", +] + +[[package]] +name = "tokio" +version = "1.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.3", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +dependencies = [ + "bitflags 2.4.0", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-livereload" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e90e6da0427c5e111e03c764d49c4e970f5a9f6569fe408e5a1cbe257f48388" +dependencies = [ + "bytes", + "http", + "http-body", + "pin-project-lite", + "tokio", + "tower", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + [[package]] name = "treehouse" version = "0.1.0" dependencies = [ + "anyhow", + "axum", "codespan-reporting", + "copy_dir", "handlebars", "pulldown-cmark", + "serde", "thiserror", + "tokio", + "tower-http", + "tower-livereload", "treehouse-format", + "watchexec", ] [[package]] name = "treehouse-format" version = "0.1.0" dependencies = [ - "log", "thiserror", ] +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "typenum" version = "1.16.0" @@ -303,6 +1917,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicode-bom" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" + [[package]] name = "unicode-ident" version = "1.0.11" @@ -321,6 +1941,90 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "watchexec" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8b97d05a9305a9aa6a7bedef64cd012ebc9b6f1f5ed0368fb48f0fe58f96988" +dependencies = [ + "async-priority-channel", + "async-recursion", + "atomic-take", + "clearscreen", + "command-group", + "futures", + "ignore-files", + "miette", + "nix", + "normalize-path", + "notify", + "once_cell", + "project-origins", + "thiserror", + "tokio", + "tracing", + "watchexec-events", + "watchexec-signals", +] + +[[package]] +name = "watchexec-events" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01603bbe02fd75918f010dadad456d47eda14fb8fdcab276b0b4b8362f142ae3" +dependencies = [ + "nix", + "notify", + "watchexec-signals", +] + +[[package]] +name = "watchexec-signals" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2a5df96c388901c94ca04055fcd51d4196ca3e971c5e805bd4a4b61dd6a7e5" +dependencies = [ + "miette", + "nix", + "thiserror", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + [[package]] name = "winapi" version = "0.3.9" @@ -351,3 +2055,144 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.3", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.3", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f51fb4c64f8b770a823c043c7fad036323e1c48f55287b7bbb7987b2fcdf3b" +dependencies = [ + "windows_aarch64_gnullvm 0.48.3", + "windows_aarch64_msvc 0.48.3", + "windows_i686_gnu 0.48.3", + "windows_i686_msvc 0.48.3", + "windows_x86_64_gnu 0.48.3", + "windows_x86_64_gnullvm 0.48.3", + "windows_x86_64_msvc 0.48.3", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde1bb55ae4ce76a597a8566d82c57432bc69c039449d61572a7a353da28f68c" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1513e8d48365a78adad7322fd6b5e4c4e99d92a69db8df2d435b25b1f1f286d4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60587c0265d2b842298f5858e1a5d79d146f9ee0c37be5782e92a6eb5e1d7a83" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224fe0e0ffff5d2ea6a29f82026c8f43870038a0ffc247aa95a52b47df381ac4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62fc52a0f50a088de499712cbc012df7ebd94e2d6eb948435449d76a6287e7ad" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2093925509d91ea3d69bcd20238f4c2ecdb1a29d3c281d026a09705d0dd35f3d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ade45bc8bf02ae2aa34a9d54ba660a1a58204da34ba793c00d83ca3730b5f1" diff --git a/Cargo.toml b/Cargo.toml index 06b4dc1..d36d5e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,4 @@ resolver = "2" [workspace.dependencies] -log = "0.4.20" - treehouse-format = { path = "crates/treehouse-format" } diff --git a/content/tree/root.tree b/content/tree/root.tree index 0c3df33..7ed066f 100644 --- a/content/tree/root.tree +++ b/content/tree/root.tree @@ -4,7 +4,7 @@ - treehouse is a brand new static website generator, inspired by the likes of Jekyll and Hugo, but offering a writing experience more close to Logseq - - ie. a public braindump + - ie. a public braindump adsadasdsad - since you're here, you're probably just setting up @@ -12,7 +12,7 @@ - this special file is almost like your index.html - + the syntax is pretty simple + + the .tree syntax is pretty simple - separate blocks are delimited with a blank line @@ -28,10 +28,35 @@ - a plus `+` means that the block is hidden by default - - before the block content, there can be an arbitrary amount of TOML specifying the block config + - before the block content, there can be an arbitrary amount of TOML pecifying the block attributes - many keys are available but they aren't really documented outside of code - blocks can span multiple lines as long as they are not broken apart with a blank line - that means each block can contain at most one paragraph, unless you use dirty HTML hacks (cheater!) + + - .tree composes together with Markdown to let you format text however you want + + - here's a bunch of stuff formatted + + - # heading 1 + + - ## heading 2 + + - ### heading 3 + headings lower than this aren't really supported because c'mon who would be this crazy + + - + + - here is my favorite fluffy boy ![ralsei with a hat](https://liquidev.net/syf/art/20230723_ralsei_hat.png) + + - also a block quote + + - > Enough You Foolish Children + + - yes i will totally abuse you with deltarune references and you cannot stop me + + - ``` + this is some block of code it looks pretty cool doesn't it + ``` diff --git a/crates/treehouse-format/Cargo.toml b/crates/treehouse-format/Cargo.toml index cd10f3f..7db6b26 100644 --- a/crates/treehouse-format/Cargo.toml +++ b/crates/treehouse-format/Cargo.toml @@ -5,4 +5,3 @@ edition = "2021" [dependencies] thiserror = "1.0.47" -log = { workspace = true } diff --git a/crates/treehouse-format/src/ast.rs b/crates/treehouse-format/src/ast.rs index a380a25..4c7e51e 100644 --- a/crates/treehouse-format/src/ast.rs +++ b/crates/treehouse-format/src/ast.rs @@ -25,6 +25,7 @@ impl Roots { #[derive(Debug, Clone)] pub struct Branch { + pub indent_level: usize, pub attributes: Range, pub kind: BranchKind, pub kind_span: Range, @@ -35,6 +36,7 @@ pub struct Branch { impl From for Branch { fn from(branch: BranchEvent) -> Self { Self { + indent_level: branch.indent_level, attributes: branch.attributes, kind: branch.kind, kind_span: branch.kind_span, diff --git a/crates/treehouse/Cargo.toml b/crates/treehouse/Cargo.toml index 5d54819..ea5762a 100644 --- a/crates/treehouse/Cargo.toml +++ b/crates/treehouse/Cargo.toml @@ -4,9 +4,17 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.75" +axum = "0.6.20" codespan-reporting = "0.11.1" +copy_dir = "0.1.3" handlebars = "4.3.7" pulldown-cmark = { version = "0.9.3", default-features = false } +serde = { version = "1.0.183", features = ["derive"] } thiserror = "1.0.47" +tokio = "1.32.0" +tower-http = { version = "0.4.3", features = ["fs"] } +tower-livereload = "0.8.0" treehouse-format = { workspace = true } +watchexec = "2.3.0" diff --git a/crates/treehouse/src/html/markdown.rs b/crates/treehouse/src/html/markdown.rs new file mode 100644 index 0000000..019566a --- /dev/null +++ b/crates/treehouse/src/html/markdown.rs @@ -0,0 +1,439 @@ +// NOTE: This code is pasted pretty much verbatim from pulldown-cmark but tweaked to have my own +// cool additions. + +// Copyright 2015 Google Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//! HTML renderer that takes an iterator of events as input. + +use std::collections::HashMap; +use std::io; + +use pulldown_cmark::escape::{escape_href, escape_html, StrWrite}; +use pulldown_cmark::{Alignment, CodeBlockKind, Event, LinkType, Tag}; +use pulldown_cmark::{CowStr, Event::*}; + +enum TableState { + Head, + Body, +} + +struct HtmlWriter<'a, I, W> { + /// Iterator supplying events. + iter: I, + + /// Writer to write to. + writer: W, + + /// Whether or not the last write wrote a newline. + end_newline: bool, + + table_state: TableState, + table_alignments: Vec, + table_cell_index: usize, + numbers: HashMap, usize>, +} + +impl<'a, I, W> HtmlWriter<'a, I, W> +where + I: Iterator>, + W: StrWrite, +{ + fn new(iter: I, writer: W) -> Self { + Self { + iter, + writer, + end_newline: true, + table_state: TableState::Head, + table_alignments: vec![], + table_cell_index: 0, + numbers: HashMap::new(), + } + } + + /// Writes a new line. + fn write_newline(&mut self) -> io::Result<()> { + self.end_newline = true; + self.writer.write_str("\n") + } + + /// Writes a buffer, and tracks whether or not a newline was written. + #[inline] + fn write(&mut self, s: &str) -> io::Result<()> { + self.writer.write_str(s)?; + + if !s.is_empty() { + self.end_newline = s.ends_with('\n'); + } + Ok(()) + } + + fn run(mut self) -> io::Result<()> { + while let Some(event) = self.iter.next() { + match event { + Start(tag) => { + self.start_tag(tag)?; + } + End(tag) => { + self.end_tag(tag)?; + } + Text(text) => { + escape_html(&mut self.writer, &text)?; + self.end_newline = text.ends_with('\n'); + } + Code(text) => { + self.write("")?; + escape_html(&mut self.writer, &text)?; + self.write("")?; + } + Html(html) => { + self.write(&html)?; + } + SoftBreak => { + self.write_newline()?; + } + HardBreak => { + self.write("
\n")?; + } + Rule => { + if self.end_newline { + self.write("
\n")?; + } else { + self.write("\n
\n")?; + } + } + FootnoteReference(name) => { + let len = self.numbers.len() + 1; + self.write("")?; + let number = *self.numbers.entry(name).or_insert(len); + write!(&mut self.writer, "{}", number)?; + self.write("")?; + } + TaskListMarker(true) => { + self.write("\n")?; + } + TaskListMarker(false) => { + self.write("\n")?; + } + } + } + Ok(()) + } + + /// Writes the start of an HTML tag. + fn start_tag(&mut self, tag: Tag<'a>) -> io::Result<()> { + match tag { + Tag::Paragraph => { + if self.end_newline { + self.write("

") + } else { + self.write("\n

") + } + } + Tag::Heading(level, id, classes) => { + if self.end_newline { + self.end_newline = false; + self.write("<")?; + } else { + self.write("\n<")?; + } + write!(&mut self.writer, "{}", level)?; + if let Some(id) = id { + self.write(" id=\"")?; + escape_html(&mut self.writer, id)?; + self.write("\"")?; + } + let mut classes = classes.iter(); + if let Some(class) = classes.next() { + self.write(" class=\"")?; + escape_html(&mut self.writer, class)?; + for class in classes { + self.write(" ")?; + escape_html(&mut self.writer, class)?; + } + self.write("\"")?; + } + self.write(">") + } + Tag::Table(alignments) => { + self.table_alignments = alignments; + self.write("") + } + Tag::TableHead => { + self.table_state = TableState::Head; + self.table_cell_index = 0; + self.write("") + } + Tag::TableRow => { + self.table_cell_index = 0; + self.write("") + } + Tag::TableCell => { + match self.table_state { + TableState::Head => { + self.write(" { + self.write(" self.write(" style=\"text-align: left\">"), + Some(&Alignment::Center) => self.write(" style=\"text-align: center\">"), + Some(&Alignment::Right) => self.write(" style=\"text-align: right\">"), + _ => self.write(">"), + } + } + Tag::BlockQuote => { + if self.end_newline { + self.write("
\n") + } else { + self.write("\n
\n") + } + } + Tag::CodeBlock(info) => { + if !self.end_newline { + self.write_newline()?; + } + match info { + CodeBlockKind::Fenced(info) => { + let lang = info.split(' ').next().unwrap(); + if lang.is_empty() { + self.write("
")
+                        } else {
+                            self.write("
")
+                        }
+                    }
+                    CodeBlockKind::Indented => self.write("
"),
+                }
+            }
+            Tag::List(Some(1)) => {
+                if self.end_newline {
+                    self.write("
    \n") + } else { + self.write("\n
      \n") + } + } + Tag::List(Some(start)) => { + if self.end_newline { + self.write("
        \n") + } + Tag::List(None) => { + if self.end_newline { + self.write("
\n")?; + } + Tag::TableHead => { + self.write("\n")?; + self.table_state = TableState::Body; + } + Tag::TableRow => { + self.write("\n")?; + } + Tag::TableCell => { + match self.table_state { + TableState::Head => { + self.write("")?; + } + TableState::Body => { + self.write("")?; + } + } + self.table_cell_index += 1; + } + Tag::BlockQuote => { + self.write("\n")?; + } + Tag::CodeBlock(_) => { + self.write("\n")?; + } + Tag::List(Some(_)) => { + self.write("\n")?; + } + Tag::List(None) => { + self.write("\n")?; + } + Tag::Item => { + self.write("\n")?; + } + Tag::Emphasis => { + self.write("")?; + } + Tag::Strong => { + self.write("")?; + } + Tag::Strikethrough => { + self.write("")?; + } + Tag::Link(_, _, _) => { + self.write("")?; + } + Tag::Image(_, _, _) => (), // shouldn't happen, handled in start + Tag::FootnoteDefinition(_) => { + self.write("\n")?; + } + } + Ok(()) + } + + // run raw text, consuming end tag + fn raw_text(&mut self) -> io::Result<()> { + let mut nest = 0; + while let Some(event) = self.iter.next() { + match event { + Start(_) => nest += 1, + End(_) => { + if nest == 0 { + break; + } + nest -= 1; + } + Html(text) | Code(text) | Text(text) => { + escape_html(&mut self.writer, &text)?; + self.end_newline = text.ends_with('\n'); + } + SoftBreak | HardBreak | Rule => { + self.write(" ")?; + } + FootnoteReference(name) => { + let len = self.numbers.len() + 1; + let number = *self.numbers.entry(name).or_insert(len); + write!(&mut self.writer, "[{}]", number)?; + } + TaskListMarker(true) => self.write("[x]")?, + TaskListMarker(false) => self.write("[ ]")?, + } + } + Ok(()) + } +} + +/// Iterate over an `Iterator` of `Event`s, generate HTML for each `Event`, and +/// push it to a `String`. +/// +/// # Examples +/// +/// ``` +/// use pulldown_cmark::{html, Parser}; +/// +/// let markdown_str = r#" +/// hello +/// ===== +/// +/// * alpha +/// * beta +/// "#; +/// let parser = Parser::new(markdown_str); +/// +/// let mut html_buf = String::new(); +/// html::push_html(&mut html_buf, parser); +/// +/// assert_eq!(html_buf, r#"

hello

+///
    +///
  • alpha
  • +///
  • beta
  • +///
+/// "#); +/// ``` +pub fn push_html<'a, I>(s: &mut String, iter: I) +where + I: Iterator>, +{ + HtmlWriter::new(iter, s).run().unwrap(); +} diff --git a/crates/treehouse/src/html/mod.rs b/crates/treehouse/src/html/mod.rs new file mode 100644 index 0000000..e95633d --- /dev/null +++ b/crates/treehouse/src/html/mod.rs @@ -0,0 +1,2 @@ +mod markdown; +pub mod tree; diff --git a/crates/treehouse/src/tree_html.rs b/crates/treehouse/src/html/tree.rs similarity index 59% rename from crates/treehouse/src/tree_html.rs rename to crates/treehouse/src/html/tree.rs index 16b77eb..d8e26d7 100644 --- a/crates/treehouse/src/tree_html.rs +++ b/crates/treehouse/src/html/tree.rs @@ -1,5 +1,7 @@ use treehouse_format::{ast::Branch, pull::BranchKind}; +use super::markdown; + pub fn branch_to_html(s: &mut String, branch: &Branch, source: &str) { s.push_str("
  • "); { @@ -10,7 +12,18 @@ pub fn branch_to_html(s: &mut String, branch: &Branch, source: &str) { }); s.push_str(""); } - s.push_str(&source[branch.content.clone()]); + + let raw_block_content = &source[branch.content.clone()]; + let mut unindented_block_content = String::with_capacity(raw_block_content.len()); + let indent = " ".repeat(branch.indent_level); + for line in raw_block_content.lines() { + unindented_block_content.push_str(line.strip_prefix(&indent).unwrap_or(line)); + unindented_block_content.push('\n'); + } + + let markdown_parser = pulldown_cmark::Parser::new(&unindented_block_content); + markdown::push_html(s, markdown_parser); + if !branch.children.is_empty() { s.push_str(""); branches_to_html(s, &branch.children, source); diff --git a/crates/treehouse/src/main.rs b/crates/treehouse/src/main.rs index 48897b3..a3a941b 100644 --- a/crates/treehouse/src/main.rs +++ b/crates/treehouse/src/main.rs @@ -1,46 +1,33 @@ -mod tree_html; +mod html; +use axum::Router; use codespan_reporting::{ diagnostic::{Diagnostic, Label, LabelStyle, Severity}, files::SimpleFile, term::termcolor::{ColorChoice, StandardStream}, }; -use tree_html::branches_to_html; -use treehouse_format::{ - ast::{Branch, Roots}, - pull::Parser, -}; +use copy_dir::copy_dir; +use handlebars::Handlebars; +use html::tree::branches_to_html; +use serde::Serialize; +use tower_http::services::ServeDir; +use tower_livereload::LiveReloadLayer; +use treehouse_format::{ast::Roots, pull::Parser}; -#[derive(Debug, thiserror::Error)] -enum Error { - #[error("I/O error: {0}")] - Io(#[from] std::io::Error), - - #[error("treehouse parsing error: {0}")] - Parse(#[from] treehouse_format::ParseError), +#[derive(Serialize)] +pub struct TemplateData { + pub tree: String, } -fn print_branch(branch: &Branch, source: &str) { - fn inner(branch: &Branch, source: &str, indent_level: usize) { - for _ in 0..indent_level { - print!(" "); - } - println!( - "{} {:?}", - branch.kind.char(), - &source[branch.content.clone()] - ); - for child in &branch.children { - inner(child, source, indent_level + 1); - } - } - inner(branch, source, 0); -} - -fn main() -> Result<(), Box> { +fn regenerate() -> anyhow::Result<()> { let _ = std::fs::remove_dir_all("target/site"); std::fs::create_dir_all("target/site")?; + copy_dir("static", "target/site/static")?; + + let mut handlebars = Handlebars::new(); + handlebars.register_template_file("template/index.hbs", "template/index.hbs")?; + let root_file = std::fs::read_to_string("content/tree/root.tree")?; let parse_result = Roots::parse(&mut Parser { input: &root_file, @@ -49,13 +36,12 @@ fn main() -> Result<(), Box> { match parse_result { Ok(roots) => { - let mut html = String::from(""); - for root in &roots.branches { - print_branch(root, &root_file); - } - branches_to_html(&mut html, &roots.branches, &root_file); - std::fs::write("target/site/index.html", &html)?; - html.push_str("") + let mut tree = String::new(); + branches_to_html(&mut tree, &roots.branches, &root_file); + + let index_html = handlebars.render("template/index.hbs", &TemplateData { tree })?; + + std::fs::write("target/site/index.html", index_html)?; } Err(error) => { let writer = StandardStream::stderr(ColorChoice::Auto); @@ -77,29 +63,43 @@ fn main() -> Result<(), Box> { } } - // let mut parser = treehouse_format::Parser { - // input: &root_file, - // position: 0, - // }; - // let mut generator = HtmlGenerator::default(); - // while let Some(branch) = parser.next_branch()? { - // for _ in 0..branch.indent_level { - // print!(" "); - // } - // println!( - // "{} {:?}", - // branch.kind.char(), - // &root_file[branch.content.clone()] - // ); - // generator.add(&root_file, &branch); - // } - // std::fs::write( - // "target/site/index.html", - // format!( - // "{}", - // generator.finish() - // ), - // )?; + Ok(()) +} + +fn regenerate_or_report_error() { + eprintln!("regenerating"); + + match regenerate() { + Ok(_) => (), + Err(error) => eprintln!("error: {error:?}"), + } +} + +async fn web_server() -> anyhow::Result<()> { + let app = Router::new().nest_service("/", ServeDir::new("target/site")); + + #[cfg(debug_assertions)] + let app = app.layer(LiveReloadLayer::new()); + + Ok(axum::Server::bind(&([0, 0, 0, 0], 8080).into()) + .serve(app.into_make_service()) + .await?) +} + +async fn fallible_main() -> anyhow::Result<()> { + regenerate_or_report_error(); + + web_server().await?; + + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + match fallible_main().await { + Ok(_) => (), + Err(error) => eprintln!("fatal: {error:?}"), + } Ok(()) } diff --git a/static/css/main.css b/static/css/main.css new file mode 100644 index 0000000..77d50f1 --- /dev/null +++ b/static/css/main.css @@ -0,0 +1,75 @@ +/* Choose more pretty colors than vanilla HTML */ + +body { + background-color: rgb(255, 253, 246); + color: #333; +} + +/* Set up fonts */ + +body, +pre, +code { + font-family: 'RecVar', sans-serif; + font-size: 14px; +} + +:root { + --recursive-mono: 0.0; + --recursive-casl: 1.0; + --recursive-wght: 400; + --recursive-slnt: -2.0; + --recursive-crsv: 0.5; +} + +*, +*:before, +*:after { + font-variation-settings: + "MONO" var(--recursive-mono), + "CASL" var(--recursive-casl), + "wght" var(--recursive-wght), + "slnt" var(--recursive-slnt), + "CRSV" var(--recursive-crsv); +} + +h1 { + --recursive-slnt: 0.0; + --recursive-casl: 0.0; + --recursive-crsv: 0.0; + --recursive-wght: 900; +} + +pre, +code { + --recursive-mono: 1.0; +} + +/* Make the tree have + and - instead of the default details/summary arrow */ + +.tree details>summary { + list-style: none; + cursor: pointer; +} + +.tree li { + list-style: none; +} + +.tree details::before { + content: '+'; + opacity: 0.5; + + padding-right: 8px; + vertical-align: text-bottom; + + --recursive-mono: 1.0; +} + +.tree details[open]::before { + content: '-'; +} + +.tree details *:first-child { + display: inline-block; +} diff --git a/static/font/Recursive_VF_1.085--subset_range_english_basic.woff2 b/static/font/Recursive_VF_1.085--subset_range_english_basic.woff2 new file mode 100644 index 0000000..8ca2e1d Binary files /dev/null and b/static/font/Recursive_VF_1.085--subset_range_english_basic.woff2 differ diff --git a/static/font/Recursive_VF_1.085--subset_range_latin_1.woff2 b/static/font/Recursive_VF_1.085--subset_range_latin_1.woff2 new file mode 100644 index 0000000..c66e50b Binary files /dev/null and b/static/font/Recursive_VF_1.085--subset_range_latin_1.woff2 differ diff --git a/static/font/Recursive_VF_1.085--subset_range_latin_1_punc.woff2 b/static/font/Recursive_VF_1.085--subset_range_latin_1_punc.woff2 new file mode 100644 index 0000000..d50a1aa Binary files /dev/null and b/static/font/Recursive_VF_1.085--subset_range_latin_1_punc.woff2 differ diff --git a/static/font/Recursive_VF_1.085--subset_range_latin_ext.woff2 b/static/font/Recursive_VF_1.085--subset_range_latin_ext.woff2 new file mode 100644 index 0000000..cfb5b43 Binary files /dev/null and b/static/font/Recursive_VF_1.085--subset_range_latin_ext.woff2 differ diff --git a/static/font/Recursive_VF_1.085--subset_range_remaining.woff2 b/static/font/Recursive_VF_1.085--subset_range_remaining.woff2 new file mode 100644 index 0000000..a260591 Binary files /dev/null and b/static/font/Recursive_VF_1.085--subset_range_remaining.woff2 differ diff --git a/static/font/Recursive_VF_1.085--subset_range_vietnamese.woff2 b/static/font/Recursive_VF_1.085--subset_range_vietnamese.woff2 new file mode 100644 index 0000000..46e23f5 Binary files /dev/null and b/static/font/Recursive_VF_1.085--subset_range_vietnamese.woff2 differ diff --git a/static/font/font.css b/static/font/font.css new file mode 100644 index 0000000..1cd5bf2 --- /dev/null +++ b/static/font/font.css @@ -0,0 +1,59 @@ +/* The bare minimum English subset, plus copyright & arrows (← ↑ → ↓) & quotes (“ ” ‘ ’) & bullet (•) */ +@font-face { + font-family: 'RecVar'; + font-style: oblique 0deg 15deg; + font-weight: 300 1000; + font-display: swap; + src: url('./Recursive_VF_1.085--subset_range_english_basic.woff2') format('woff2'); + unicode-range: U+0020-007F, U+00A9, U+2190-2193, U+2018, U+2019, U+201C, U+201D, U+2022; +} + +/* unicode latin-1 letters, basic european diacritics */ +@font-face { + font-family: 'RecVar'; + font-style: oblique 0deg 15deg; + font-weight: 300 1000; + font-display: swap; + src: url('./Recursive_VF_1.085--subset_range_latin_1.woff2') format('woff2'); + unicode-range: U+00C0-00FF; +} + +/* unicode latin-1, punc/symbols & arrows (↔ ↕ ↖ ↗ ↘ ↙) */ +@font-face { + font-family: 'RecVar'; + font-style: oblique 0deg 15deg; + font-weight: 300 1000; + font-display: swap; + src: url('./Recursive_VF_1.085--subset_range_latin_1_punc.woff2') format('woff2'); + unicode-range: U+00A0-00A8, U+00AA-00BF, U+2194-2199; +} + +/* unicode latin A extended */ +@font-face { + font-family: 'RecVar'; + font-style: oblique 0deg 15deg; + font-weight: 300 1000; + font-display: swap; + src: url('./Recursive_VF_1.085--subset_range_latin_ext.woff2') format('woff2'); + unicode-range: U+0100-017F; +} + +/* unicodes for vietnamese */ +@font-face { + font-family: 'RecVar'; + font-style: oblique 0deg 15deg; + font-weight: 300 1000; + font-display: swap; + src: url('./Recursive_VF_1.085--subset_range_vietnamese.woff2') format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} + +/* remaining Unicodes */ +@font-face { + font-family: 'RecVar'; + font-style: oblique 0deg 15deg; + font-weight: 300 1000; + font-display: swap; + src: url('./Recursive_VF_1.085--subset_range_remaining.woff2') format('woff2'); + unicode-range: U+2007, U+2008, U+2009, U+200A, U+200B, U+D, U+2010, U+2012, U+2013, U+2014, U+2015, U+201A, U+201E, U+2020, U+2021, U+2026, U+2030, U+2032, U+2033, U+2039, U+203A, U+203E, U+2044, U+2052, U+2070, U+2074, U+2075, U+2076, U+2077, U+2078, U+2079, U+207B, U+2080, U+2081, U+2082, U+2083, U+2084, U+2085, U+2086, U+2087, U+2088, U+2089, U+20A1, U+20A6, U+20A8, U+20A9, U+20AA, U+20AC, U+20AD, U+20B1, U+20B2, U+20B4, U+20B5, U+20B8, U+20B9, U+20BA, U+20BC, U+20BD, U+20BF, U+F8FF, U+2113, U+2116, U+2122, U+2126, U+212E, U+E132, U+E133, U+2153, U+2154, U+215B, U+215C, U+215D, U+215E, U+18F, U+192, U+19D, U+1C4, U+1C5, U+1C6, U+1C7, U+1C8, U+1C9, U+1CA, U+1CB, U+1CC, U+1E6, U+1E7, U+1EA, U+1EB, U+1F1, U+1F2, U+1F3, U+1FA, U+1FB, U+1FC, U+1FD, U+1FE, U+1FF, U+200, U+201, U+202, U+203, U+204, U+205, U+206, U+207, U+208, U+209, U+20A, U+20B, U+20C, U+20D, U+20E, U+20F, U+210, U+211, U+212, U+213, U+214, U+215, U+216, U+217, U+218, U+219, U+21A, U+21B, U+2215, U+2219, U+221E, U+221A, U+22A, U+22B, U+22C, U+22D, U+222B, U+230, U+231, U+232, U+233, U+2236, U+237, U+2248, U+259, U+2260, U+2261, U+2264, U+2265, U+272, U+2B9, U+2BA, U+2BB, U+2BC, U+2BE, U+2BF, U+2C6, U+2C7, U+2C8, U+2C9, U+2CA, U+2CB, U+2D8, U+2D9, U+2DA, U+2DB, U+2DC, U+2DD, U+300, U+301, U+FB02, U+FB03, U+302, U+303, U+304, U+FB01, U+306, U+307, U+308, U+309, U+30A, U+30B, U+30C, U+30F, U+311, U+312, U+315, U+31B, U+2202, U+323, U+324, U+325, U+326, U+327, U+328, U+329, U+2205, U+32E, U+2206, U+331, U+335, U+220F, U+2211, U+2212, U+391, U+392, U+393, U+394, U+398, U+39B, U+39C, U+39D, U+3A0, U+3A6, U+3B1, U+3B2, U+3B3, U+3B4, U+3B8, U+3BB, U+3BC, U+3BD, U+3C0, U+3C6, U+25A0, U+25A1, U+25B2, U+25B3, U+25B6, U+25B7, U+25BC, U+25BD, U+25C0, U+25C1, U+25C6, U+25C7, U+25CA, U+1E08, U+1E09, U+1E0C, U+1E0D, U+1E0E, U+1E0F, U+2610, U+2611, U+1E14, U+1E15, U+1E16, U+1E17, U+1E1C, U+1E1D, U+1E20, U+1E21, U+1E24, U+1E25, U+1E2A, U+1E2B, U+1E2E, U+1E2F, U+1E36, U+1E37, U+1E3A, U+1E3B, U+E3F, U+1E42, U+1E43, U+1E44, U+1E45, U+1E46, U+1E47, U+1E48, U+1E49, U+1E4C, U+1E4D, U+1E4E, U+1E4F, U+1E50, U+1E51, U+1E52, U+1E53, U+1E5A, U+1E5B, U+1E5E, U+1E5F, U+1E60, U+2661, U+1E61, U+1E62, U+1E63, U+1E64, U+1E65, U+1E66, U+1E67, U+1E68, U+1E69, U+2665, U+1E6C, U+1E6D, U+1E6E, U+1E6F, U+1E78, U+1E79, U+1E7A, U+1E7B, U+1E80, U+1E81, U+1E82, U+1E83, U+1E84, U+1E85, U+1E8E, U+1E8F, U+1E92, U+1E93, U+1E97, U+1E9E, U+2713, U+27E8, U+27E9; +} diff --git a/static/js/usability.js b/static/js/usability.js new file mode 100644 index 0000000..e1192c2 --- /dev/null +++ b/static/js/usability.js @@ -0,0 +1,10 @@ +// Bits and pieces to make vanilla HTML just a bit more usable. + +// We want to let the user have a selection on collapsible blocks without collapsing them when +// the user finishes marking their selection. +document.addEventListener("click", event => { + console.log(getSelection()); + if (getSelection().type == "Range") { + event.preventDefault(); + } +}) diff --git a/static/main.css b/static/main.css deleted file mode 100644 index e69de29..0000000 diff --git a/template/index.hbs b/template/index.hbs index 16366e0..0c9367f 100644 --- a/template/index.hbs +++ b/template/index.hbs @@ -3,12 +3,20 @@ + + {{ config.user.title }} - + + + + + - {{{ tree }}} +
    + {{{ tree }}} +