Compare commits
2 Commits
2b02ffb79f
...
42a9aba590
| Author | SHA1 | Date | |
|---|---|---|---|
| 42a9aba590 | |||
| aac5804d95 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
target
|
||||||
|
.idea
|
||||||
768
Cargo.lock
generated
Normal file
768
Cargo.lock
generated
Normal file
@ -0,0 +1,768 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288"
|
||||||
|
dependencies = [
|
||||||
|
"axum-core",
|
||||||
|
"bytes",
|
||||||
|
"form_urlencoded",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper",
|
||||||
|
"hyper-util",
|
||||||
|
"itoa",
|
||||||
|
"matchit",
|
||||||
|
"memchr",
|
||||||
|
"mime",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rustversion",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_path_to_error",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper",
|
||||||
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-core"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http-body-util",
|
||||||
|
"mime",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rustversion",
|
||||||
|
"sync_wrapper",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"pin-project-lite",
|
||||||
|
"pin-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-body"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-body-util"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httpdate"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"httparse",
|
||||||
|
"httpdate",
|
||||||
|
"itoa",
|
||||||
|
"pin-project-lite",
|
||||||
|
"smallvec",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-util"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"hyper",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "json5"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.171"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchit"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
|
||||||
|
dependencies = [
|
||||||
|
"adler2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.36.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"thiserror",
|
||||||
|
"ucd-trie",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_derive"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_generator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_generator"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_meta",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_meta"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"pest",
|
||||||
|
"sha2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.94"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_path_to_error"
|
||||||
|
version = "0.1.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
|
||||||
|
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 = "sha2"
|
||||||
|
version = "0.10.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sync_wrapper"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.44.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"pin-project-lite",
|
||||||
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
"sync_wrapper",
|
||||||
|
"tokio",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-layer"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-service"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-core"
|
||||||
|
version = "0.1.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-trie"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yyyi_ru"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"json5",
|
||||||
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "yyyi_ru"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = "0.8.3"
|
||||||
|
tokio = { version = "1.44.1", features = ["rt-multi-thread"] }
|
||||||
|
json5 = "0.4.1"
|
||||||
|
serde_json = "1.0.140"
|
||||||
3
assets/HypertextPages/aboutme/en-US.html
Normal file
3
assets/HypertextPages/aboutme/en-US.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
I am Andreev Gregory ({{age}} y.o.),
|
||||||
|
living in Moscow, learning programming, big fond of making patches to dwm, sometimes write some unhinged ravings.
|
||||||
|
Most interesting stuff about me gets published <a href="/blog">here</a>.
|
||||||
3
assets/HypertextPages/aboutme/ru-RU.html
Normal file
3
assets/HypertextPages/aboutme/ru-RU.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Я Андреев Григорий ({{age}}),
|
||||||
|
живу в Москве, учусь прогать, люблю курить dwm и иногда пишу разного рода дичь.
|
||||||
|
Самым интересным в своей жизни делюсь <a href="/blog">вот здесь</a>.
|
||||||
12
assets/HypertextPages/blog.html
Normal file
12
assets/HypertextPages/blog.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
|
<title>Блог Гриши</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
assets/HypertextPages/index.html
Normal file
18
assets/HypertextPages/index.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{% import "lang_macro.html" as lang_macro %}
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
|
<title>{{pres.index.title}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="main-container">
|
||||||
|
<div>
|
||||||
|
<h2 class="">{{pres.index.about_me_header}}</h2>
|
||||||
|
<p class="description-text">{% if aboutme_template is string %} STRING {{lang_macro::incl('aboutme/')}} {% else %} NOT STRING{%endif%}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
assets/HypertextPages/lang-macro.html
Normal file
0
assets/HypertextPages/lang-macro.html
Normal file
42
assets/css/common.css
Normal file
42
assets/css/common.css
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
body, html {
|
||||||
|
background-color: #151715;
|
||||||
|
color: white;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-container {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-justify-content-center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-text {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: aqua;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: deepskyblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #4c259a;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited:hover {
|
||||||
|
color: #613d9c;
|
||||||
|
}
|
||||||
6
assets/text/en-US.json5
Normal file
6
assets/text/en-US.json5
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
index: {
|
||||||
|
title: "Gregory's title page",
|
||||||
|
about_me_header: "About me",
|
||||||
|
}
|
||||||
|
}
|
||||||
6
assets/text/ru-RU.json5
Normal file
6
assets/text/ru-RU.json5
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
index: {
|
||||||
|
title: "Гришина заглавная страничка",
|
||||||
|
about_me_header: "Обо мне",
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod yyyi_ru;
|
||||||
|
pub mod mtgott;
|
||||||
6
src/main.rs
Normal file
6
src/main.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use yyyi_ru::yyyi_ru::MAIN;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
MAIN().await
|
||||||
|
}
|
||||||
27
src/mtgott/charclasses.rs
Normal file
27
src/mtgott/charclasses.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use std::ops::RangeBounds;
|
||||||
|
|
||||||
|
pub fn is_whitespace(ch: char) -> bool {
|
||||||
|
ch == '\t' && ch == '\n' && ch == ' ' && ch == '\r'
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_digit(ch: char) -> bool {
|
||||||
|
('0'..='9').contains(&ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_normal_word_constituent(ch: char) -> bool {
|
||||||
|
('0'..='9').contains(&ch) || ('a'..='z').contains(&ch) || ('A'..='Z').contains(&ch)
|
||||||
|
|| '-' == ch || '_' == ch
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_normal_word(s: &str) -> bool {
|
||||||
|
s.chars().all( is_normal_word_constituent)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn escape_for_html(s: &str) -> String {
|
||||||
|
s.replace("&", "&amd;").replace("<", "<").replace(">", ">")
|
||||||
|
.replace("'", "'").replace("\"", """)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_illegal_name(s: &str) -> bool {
|
||||||
|
s != "_" && s != "if" && s != "else" && s != "for" && s != "let" && s != "self" && s != "super"
|
||||||
|
}
|
||||||
386
src/mtgott/mod.rs
Normal file
386
src/mtgott/mod.rs
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
mod charclasses;
|
||||||
|
|
||||||
|
use serde_json;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use charclasses::*;
|
||||||
|
|
||||||
|
struct CallExpression {
|
||||||
|
callee: Option<Box<Expression>>,
|
||||||
|
arguments: Vec<Box<Expression>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Expression {
|
||||||
|
Root(),
|
||||||
|
Argument(u64),
|
||||||
|
Get(Box<Expression>, Box<Expression>),
|
||||||
|
Attribute(Box<Expression>, String),
|
||||||
|
Call(Box<Expression>, Box<Expression>),
|
||||||
|
Int(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IfSubElement {
|
||||||
|
branches: Vec<Element>,
|
||||||
|
conditions: Vec<Expression>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ForSubElement {
|
||||||
|
iterable: Expression,
|
||||||
|
hold_key: bool,
|
||||||
|
hold_value: bool,
|
||||||
|
core: Element,
|
||||||
|
/* Either "\n", " " or "" */
|
||||||
|
join: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SubElement{
|
||||||
|
Static(String),
|
||||||
|
/* ======== Other are dynamic ======== */
|
||||||
|
If(IfSubElement),
|
||||||
|
/* Both for {{}} and {[]} */
|
||||||
|
InsertExpr(Expression),
|
||||||
|
For(ForSubElement),
|
||||||
|
Let(Expression, Element),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Element {
|
||||||
|
argc: usize,
|
||||||
|
sub_elements: Vec<SubElement>
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Plemege {
|
||||||
|
Element(Element),
|
||||||
|
Package(Box<HashMap<String, Plemege>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum FileParsingErrorKind {
|
||||||
|
expected_pack_opening_or_element_opening_or_pack_ending,
|
||||||
|
expected_pack_opening_or_element_opening_or_eof,
|
||||||
|
unmatched_pack_ending_tag,
|
||||||
|
expected_pack_name,
|
||||||
|
illegal_pack_name,
|
||||||
|
pack_member_name_already_occupied,
|
||||||
|
expected_pack_opening_tag_end,
|
||||||
|
expected_element_name,
|
||||||
|
illegal_element_name,
|
||||||
|
expected_argument_name_or_eldef_opening_tag_end,
|
||||||
|
illegal_argument_name,
|
||||||
|
repeated_argument_name,
|
||||||
|
expected_command_name,
|
||||||
|
incorrect_block_ending_tag_expected_normal,
|
||||||
|
expected_write_tag_end_after_expression,
|
||||||
|
expected_roughinsert_tag_end_after_expression,
|
||||||
|
illegal_command_name,
|
||||||
|
expected_cmd_tag_end,
|
||||||
|
}
|
||||||
|
|
||||||
|
use FileParsingErrorKind::*;
|
||||||
|
|
||||||
|
pub struct FileParsingError {
|
||||||
|
kind: FileParsingErrorKind,
|
||||||
|
p1: usize,
|
||||||
|
p2: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileParsingError {
|
||||||
|
fn new(kind: FileParsingErrorKind, p1: usize, p2: usize) -> Self {
|
||||||
|
Self{kind, p1, p2}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Parser<'a> {
|
||||||
|
text: &'a str,
|
||||||
|
p: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parser {
|
||||||
|
fn here(&self)->Option<char> {
|
||||||
|
self.text[self.p..].chars().next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_ahead(&self, substr: &[u8])->bool {
|
||||||
|
self.text[self.p..].starts_with(substr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn advance(&mut self) {
|
||||||
|
self.p += self.text[self.p..].char_indices().next().unwrap().0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_whitespace(&mut self) {
|
||||||
|
loop {
|
||||||
|
match self.here() {
|
||||||
|
Some(ch ) => if !is_whitespace(ch) {
|
||||||
|
break
|
||||||
|
} else { self.advance(); }
|
||||||
|
None => break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_normal_word(&mut self){
|
||||||
|
loop {
|
||||||
|
match self.here() {
|
||||||
|
Some(ch ) => if !is_normal_word_constituent(ch) {
|
||||||
|
break
|
||||||
|
} else { self.advance(); }
|
||||||
|
None => break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_unexpected_char_error(&self, kind: FileParsingErrorKind) -> FileParsingError {
|
||||||
|
match self.text[self.p..].char_indices().next() {
|
||||||
|
Some((off, _)) => FileParsingError::new(kind, self.p, self.p + off),
|
||||||
|
None => FileParsingError::new(kind, self.p, self.p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_pack_plus_ending(&mut self, top: bool) -> Result<Plemege::Package, FileParsingError> {
|
||||||
|
let mut res: HashMap<String, Plemege> = HashMap::new();
|
||||||
|
loop {
|
||||||
|
self.skip_whitespace();
|
||||||
|
if self.p == self.text.len() {
|
||||||
|
return if top {
|
||||||
|
Ok(Plemege::Package(Box::new(res)))
|
||||||
|
} else {
|
||||||
|
Err(self.new_unexpected_char_error(expected_pack_opening_or_element_opening_or_pack_ending))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.is_ahead(&[b'{', b'$', b'}']) {
|
||||||
|
if top {
|
||||||
|
return Err(FileParsingError::new(unmatched_pack_ending_tag, self.p, self.p + 3))
|
||||||
|
} else {
|
||||||
|
self.p += 3;
|
||||||
|
return Ok(res);
|
||||||
|
}
|
||||||
|
} else if self.is_ahead(&[b'{', b'$']) {
|
||||||
|
self.p += 2;
|
||||||
|
self.skip_whitespace();
|
||||||
|
let p1 = self.p;
|
||||||
|
self.skip_normal_word();
|
||||||
|
if self.p == p1 {
|
||||||
|
return Err(self.new_error(expected_pack_name))
|
||||||
|
}
|
||||||
|
let child_name: &str = &self.text[p1..self.p];
|
||||||
|
if !is_illegal_name(child_name) {
|
||||||
|
return Err(FileParsingError::new(illegal_pack_name, p1, self.p))
|
||||||
|
}
|
||||||
|
if let Some(_) = res.get(child_name) {
|
||||||
|
return Err(FileParsingError::new(pack_member_name_already_occupied, p1, self.p))
|
||||||
|
}
|
||||||
|
self.skip_normal_word();
|
||||||
|
if !self.is_ahead(&[b'$', b'}']) {
|
||||||
|
return Err(self.new_unexpected_char_error(expected_pack_opening_tag_end))
|
||||||
|
}
|
||||||
|
self.p += 2;
|
||||||
|
res.insert(String::from(child_name), self.parse_pack_plus_ending(false));
|
||||||
|
} else if self.is_ahead(&[b'{', b'@']) {
|
||||||
|
self.p += 2;
|
||||||
|
self.skip_whitespace();
|
||||||
|
let p1 = self.p;
|
||||||
|
self.skip_normal_word();
|
||||||
|
if p1 == self.p {
|
||||||
|
return Err(FileParsingError::new(expected_element_name, p1, self.p))
|
||||||
|
}
|
||||||
|
let child_name = &self.text[p1..self.p];
|
||||||
|
if is_illegal_name(child_name) {
|
||||||
|
return Err(FileParsingError::new(illegal_element_name, p1, self.p))
|
||||||
|
}
|
||||||
|
if let Some(_) = res.get(child_name) {
|
||||||
|
return Err(FileParsingError::new(pack_member_name_already_occupied, p1, self.p))
|
||||||
|
}
|
||||||
|
let mut arg_names: Vec<&str> = Vec::new();
|
||||||
|
loop {
|
||||||
|
self.skip_whitespace();
|
||||||
|
if self.is_ahead(&[b'@', b'}']) {
|
||||||
|
self.p += 2;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let p1 = self.p;
|
||||||
|
self.skip_normal_word();
|
||||||
|
if p1 == self.p {
|
||||||
|
return Err(FileParsingError::new(expected_argument_name_or_eldef_opening_tag_end, p1, self.p))
|
||||||
|
}
|
||||||
|
let arg_name: &str = &self.text[p1..self.p];
|
||||||
|
if is_illegal_name(arg_name) {
|
||||||
|
return Err(FileParsingError::new(illegal_argument_name, p1, self.p))
|
||||||
|
}
|
||||||
|
if arg_names.iter().any(|b: &str| b == arg_name) {
|
||||||
|
return Err(FileParsingError::new(repeated_argument_name, p1, self.p))
|
||||||
|
}
|
||||||
|
arg_names.push(arg_name);
|
||||||
|
}
|
||||||
|
let (child_el, end_cmd): (Element, ReasonOfElementEnd) = self.parse_element_plus_ending(arg_names)?;
|
||||||
|
if end_cmd.cmd != BlockEndingCmdTag::NORMAL {
|
||||||
|
return Err(FileParsingError::new(incorrect_block_ending_tag_expected_normal, end_cmd.p1, self.p))
|
||||||
|
}
|
||||||
|
res.insert(child_name, child_el);
|
||||||
|
} else {
|
||||||
|
self.new_unexpected_char_error(if top {
|
||||||
|
expected_pack_opening_or_element_opening_or_eof
|
||||||
|
} else {
|
||||||
|
expected_pack_opening_or_element_opening_or_pack_ending
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BlockEndingCmdTag {
|
||||||
|
NORMAL,
|
||||||
|
LF,
|
||||||
|
GAP,
|
||||||
|
NOGAP,
|
||||||
|
ENDLOOP,
|
||||||
|
ELSE_IF,
|
||||||
|
ELSE,
|
||||||
|
ENDIF
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReasonOfElementEnd {
|
||||||
|
p1: usize,
|
||||||
|
cmd: BlockEndingCmdTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parser {
|
||||||
|
/* If BlockEndingCmdTag::ELSE_IF is returned, the ending tag won't be read completely,
|
||||||
|
* But in other case it would be read to the end */
|
||||||
|
fn parse_element_plus_ending_tag(&mut self, arg_names: Vec<&str>) -> Result<(Element, ReasonOfElementEnd), FileParsingError> {
|
||||||
|
let mut res: Vec<SubElement> = Vec::new();
|
||||||
|
let mut tp1 = self.p;
|
||||||
|
|
||||||
|
let fin_static = || {
|
||||||
|
if tp1 < self.p {
|
||||||
|
res.push(SubElement::Static(String::from(&self.text[tp1..self.p])))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Fixes whitespaces in */
|
||||||
|
let finishing_touches = |ree: ReasonOfElementEnd| -> Result<(Element, ReasonOfElementEnd), FileParsingError> {
|
||||||
|
Ok((Element{ argc: arg_names.count(), sub_elements: res }, ree))
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if self.is_ahead(&[b'{', b'{']) {
|
||||||
|
fin_static();
|
||||||
|
self.p += 2;
|
||||||
|
let (expr, tt) = self.parse_expression()?;
|
||||||
|
if tt != ExpressionEndingTagEnd::Write {
|
||||||
|
return Err(FileParsingError::new(expected_write_tag_end_after_expression, self.p - 2, self.p))
|
||||||
|
}
|
||||||
|
res.push(SubElement::InsertExpr(
|
||||||
|
Expression::Call(
|
||||||
|
Box::new(Expression::Attribute(
|
||||||
|
Box::new(Expression::Root()), "sanitize"
|
||||||
|
)),
|
||||||
|
expr)
|
||||||
|
));
|
||||||
|
tp1 = self.p;
|
||||||
|
} else if self.is_ahead(&[b'{', b'[']) {
|
||||||
|
fin_static();
|
||||||
|
self.p += 2;
|
||||||
|
let (expr, tt) = self.parse_expression()?;
|
||||||
|
if tt != ExpressionEndingTagEnd::RoughInsert {
|
||||||
|
return Err(FileParsingError::new(expected_roughinsert_tag_end_after_expression, self.p - 2, self.p))
|
||||||
|
}
|
||||||
|
res.push(SubElement::InsertExpr(expr));
|
||||||
|
} else if self.is_ahead(&[b'{', b'%', b'}']) {
|
||||||
|
fin_static();
|
||||||
|
self.p += 3;
|
||||||
|
return finishing_touches(ReasonOfElementEnd{p1: self.p - 3, cmd: BlockEndingCmdTag::NORMAL});
|
||||||
|
} else if self.is_ahead(&[b'{', b'%']) {
|
||||||
|
fin_static();
|
||||||
|
/* Might be needed if this is the ENDING cmd tag */
|
||||||
|
let p1 = self.p;
|
||||||
|
self.p += 2;
|
||||||
|
self.skip_whitespace();
|
||||||
|
let pb = self.p;
|
||||||
|
self.skip_normal_word();
|
||||||
|
if pb == self.p {
|
||||||
|
return Err(self.new_unexpected_char_error(expected_command_name))
|
||||||
|
}
|
||||||
|
let cmd = &self.text[pb..self.p];
|
||||||
|
|
||||||
|
/* Read space + expect %} and do finishing_touches */
|
||||||
|
let just_one_thing = |cmd: BlockEndingCmdTag| -> Result<(Element, ReasonOfElementEnd), FileParsingError> {
|
||||||
|
self.skip_whitespace();
|
||||||
|
if !self.is_ahead(&[b'%', b'}']) {
|
||||||
|
return self.new_unexpected_char_error(expected_cmd_tag_end);
|
||||||
|
}
|
||||||
|
self.p += 2;
|
||||||
|
finishing_touches(ReasonOfElementEnd{p1, cmd})
|
||||||
|
};
|
||||||
|
|
||||||
|
match cmd {
|
||||||
|
"lf" => return just_one_thing(BlockEndingCmdTag::LF),
|
||||||
|
"gap" => return just_one_thing(BlockEndingCmdTag::GAP),
|
||||||
|
"nogap" => return just_one_thing(BlockEndingCmdTag::NOGAP),
|
||||||
|
"else" => {
|
||||||
|
self.skip_whitespace();
|
||||||
|
let ps = self.p;
|
||||||
|
self.skip_normal_word();
|
||||||
|
if ps == self.p {
|
||||||
|
return just_one_thing(BlockEndingCmdTag::ELSE)
|
||||||
|
} else if self.text[ps..self.p] != "if" {
|
||||||
|
return Err(FileParsingError::new(illegal_command_name, pb, self.p))
|
||||||
|
}
|
||||||
|
return finishing_touches(ReasonOfElementEnd{p1, cmd: BlockEndingCmdTag::ELSE_IF})
|
||||||
|
}
|
||||||
|
"endif" => return just_one_thing(BlockEndingCmdTag::ENDIF),
|
||||||
|
"endloop" => return just_one_thing(BlockEndingCmdTag::ENDLOOP),
|
||||||
|
"for" => res.push(self.parse_let(&arg_names)?),
|
||||||
|
"if" => res.push(self.parse_if(&arg_names)?),
|
||||||
|
"let" => res.push(self.parse_let(&arg_names)?),
|
||||||
|
_ => return Err(FileParsingError::new(illegal_command_name, pb, self.p)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It turned out to be so complex I put it in a separate function.
|
||||||
|
* It parses expr %} block {% else if expr %} block {% else %} block {%} */
|
||||||
|
fn parse_if(&mut self, arg_names: &Vec<&str>) -> Result<SubElement::If, FileParsingError> {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_let(&mut self, arg_names: &Vec<&str>) -> Result<SubElement::Let, FileParsingError> {
|
||||||
|
self.skip_whitespace();
|
||||||
|
let p1 = self.p;
|
||||||
|
self.skip_normal_word();
|
||||||
|
if p1 == self.p {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_for(&mut self, arg_names: &Vec<&str>) -> Result<SubElement::For, FileParsingError> {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ExpressionEndingTagEnd {
|
||||||
|
Write, RoughInsert, Cmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parser {
|
||||||
|
fn parse_expression_plus_tag_end(&mut self) -> Result<(Expression, ExpressionEndingTagEnd), FileParsingError> {
|
||||||
|
self.skip_whitespace();
|
||||||
|
return Err(self.new_unexpected_char_error(expected_pack_name)) // todo
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_one_file(text: &str) -> Result<Plemege::Package, FileParsingError> {
|
||||||
|
let mut parser: Parser = Parser{text, p: 0};
|
||||||
|
parser.parse_pack_plus_ending(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests{
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn t1 () {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
163
src/yyyi_ru/mod.rs
Normal file
163
src/yyyi_ru/mod.rs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
use axum;
|
||||||
|
use std::io;
|
||||||
|
use std::fs;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use axum::http::HeaderValue;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use axum::http;
|
||||||
|
use json5;
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct StaticAsset {
|
||||||
|
content_type: HeaderValue,
|
||||||
|
content: Vec<u8>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AssetsCache {
|
||||||
|
// templates: tera::Tera,
|
||||||
|
static_assets: HashMap<String, StaticAsset>,
|
||||||
|
missing_text: Vec<(String, serde_json::Value)>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExtensionContentTypeCorr{
|
||||||
|
extension: &'static str,
|
||||||
|
content_type: HeaderValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_static_html_page(p: &Path) -> io::Result<StaticAsset> {
|
||||||
|
Ok(StaticAsset {
|
||||||
|
content_type: HeaderValue::from_str("text/html").unwrap(),
|
||||||
|
content: fs::read(p)?
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_static_assets(p: &Path, need: &[ExtensionContentTypeCorr]) -> io::Result<HashMap<String, StaticAsset>> {
|
||||||
|
if !p.is_dir() {
|
||||||
|
return Err(io::Error::from(io::ErrorKind::NotADirectory))
|
||||||
|
}
|
||||||
|
let mut st: HashMap<String, StaticAsset> = HashMap::new();
|
||||||
|
let mut td: Vec<String> = vec![String::new()];
|
||||||
|
while td.len() > 0 {
|
||||||
|
let dshp_dir: String = td.pop().unwrap();
|
||||||
|
let p_dir = p.join(dshp_dir.clone());
|
||||||
|
for entry in fs::read_dir(p_dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let dshp_child = if dshp_dir.len() > 0 {
|
||||||
|
format!("{dshp_dir}/{}", entry.file_name().to_str().unwrap())
|
||||||
|
} else {
|
||||||
|
String::from(entry.file_name().to_str().unwrap())
|
||||||
|
};
|
||||||
|
let p_child = p.join(dshp_child.clone());
|
||||||
|
if p_child.is_dir() {
|
||||||
|
td.push(dshp_child);
|
||||||
|
} else {
|
||||||
|
if let Some(ext) = need.iter().find(|ext| {dshp_child.ends_with(ext.extension)}) {
|
||||||
|
st.insert(dshp_child.clone(), StaticAsset {
|
||||||
|
content_type: ext.content_type.clone(),
|
||||||
|
content: fs::read(p.join(dshp_child))?
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(st)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_needed_static_assets(p: &Path) -> io::Result<HashMap<String, StaticAsset>> {
|
||||||
|
load_static_assets(p, &[
|
||||||
|
ExtensionContentTypeCorr{extension: ".css", content_type: HeaderValue::from_str("text/css").unwrap()},
|
||||||
|
ExtensionContentTypeCorr{extension: ".jpeg", content_type: HeaderValue::from_str("image/jpeg").unwrap()},
|
||||||
|
ExtensionContentTypeCorr{extension: ".jpg", content_type: HeaderValue::from_str("image/jpeg").unwrap()},
|
||||||
|
ExtensionContentTypeCorr{extension: ".png", content_type: HeaderValue::from_str("image/png").unwrap()},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_missing_text(assets: &Path) -> Result<Vec<(String, serde_json::Value)>, Box<dyn std::error::Error>> {
|
||||||
|
let languages = ["ru-RU", "en-US"];
|
||||||
|
let mut res: Vec<(String, serde_json::Value)> = Vec::with_capacity(languages.len());
|
||||||
|
for language in languages {
|
||||||
|
let fc = &fs::read(&assets.join(String::from("text/") + language + ".json5"))?;
|
||||||
|
let val: serde_json::Value = json5::from_str(std::str::from_utf8(fc)?)?;
|
||||||
|
res.push((String::from(language), val))
|
||||||
|
}
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_assets(assets_dir: &Path) -> AssetsCache {
|
||||||
|
// let tera_st = tera::Tera::new(
|
||||||
|
// &assets_dir.join("HypertextPages/**/*.html").to_str().unwrap()
|
||||||
|
// );
|
||||||
|
// if let Err(err) = &tera_st {
|
||||||
|
// println!("{err}")
|
||||||
|
// }
|
||||||
|
AssetsCache {
|
||||||
|
// templates: tera_st.unwrap(),
|
||||||
|
static_assets: load_needed_static_assets(assets_dir).expect("Failed to load static assets"),
|
||||||
|
missing_text: load_missing_text(assets_dir).expect("Failed to load gap-text")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn static_assets(
|
||||||
|
axum::extract::Path(path): axum::extract::Path<String>,
|
||||||
|
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>,
|
||||||
|
) -> Result<([(axum::http::HeaderName, axum::http::HeaderValue); 1], Vec<u8>), axum::http::StatusCode> {
|
||||||
|
if let Some(file) = assets.static_assets.get(&path) {
|
||||||
|
return Ok((
|
||||||
|
[(http::header::CONTENT_TYPE, file.content_type.clone())],
|
||||||
|
file.content.clone()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Err(axum::http::StatusCode::NOT_FOUND)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn page_index(
|
||||||
|
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>,
|
||||||
|
// axum::extract::Extension(t): axum::extract::Extension<tera::Tera>
|
||||||
|
) -> axum::response::Html<String> {
|
||||||
|
// let mut context = tera::Context::new();
|
||||||
|
// let lang = &assets.missing_text[0].0;
|
||||||
|
// context.insert("lang", lang);
|
||||||
|
// context.insert("pres", &assets.missing_text[0].1);
|
||||||
|
// context.insert("age", &14);
|
||||||
|
// context.insert("aboutme_template", &(String::from("aboutme/") + lang + ".html"));
|
||||||
|
// axum::response::Html(assets.templates.render("index.html", &context).expect("Tera failure"))
|
||||||
|
axum::response::Html(String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn page_blog(
|
||||||
|
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>,
|
||||||
|
// axum::extract::Extension(t): axum::extract::Extension<tera::Tera>
|
||||||
|
) -> impl axum::response::IntoResponse {
|
||||||
|
// let mut context = tera::Context::new();
|
||||||
|
// context.insert("lang", &assets.missing_text[0].0);
|
||||||
|
// context.insert("pres", &assets.missing_text[0].1);
|
||||||
|
// axum::response::Html(assets.templates.render("blog.html", &context).expect("Tera failure"))
|
||||||
|
axum::response::Html(String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fallback_page() -> axum::http::StatusCode {
|
||||||
|
axum::http::StatusCode::NOT_FOUND
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn MAIN() {
|
||||||
|
let assets_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("assets");
|
||||||
|
println!("Cargo manifest dir: {assets_dir:?}");
|
||||||
|
|
||||||
|
let assets = Arc::new(load_assets(&assets_dir));
|
||||||
|
|
||||||
|
// build our application with a single route
|
||||||
|
let app = axum::Router::new()
|
||||||
|
.without_v07_checks()
|
||||||
|
.route("/", axum::routing::MethodRouter::new().get(page_index))
|
||||||
|
.route("/assets/{*path}", axum::routing::get(static_assets))
|
||||||
|
.route("/blog", axum::routing::get(page_blog))
|
||||||
|
.fallback(fallback_page).with_state(assets);
|
||||||
|
// .layer(axum::Extension(templates));
|
||||||
|
|
||||||
|
// run our app with hyper, listening globally on port 3000
|
||||||
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user