Started writing MTGOTT

This commit is contained in:
Андреев Григорий 2025-04-04 19:45:42 +03:00
parent aac5804d95
commit 42a9aba590
12 changed files with 535 additions and 688 deletions

625
Cargo.lock generated
View File

@ -17,36 +17,6 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.8.3" version = "0.8.3"
@ -116,12 +86,6 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.4" version = "0.10.4"
@ -131,83 +95,18 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bstr"
version = "1.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.10.1" version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
dependencies = [
"shlex",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"windows-link",
]
[[package]]
name = "chrono-tz"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb"
dependencies = [
"chrono",
"chrono-tz-build",
"phf",
]
[[package]]
name = "chrono-tz-build"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1"
dependencies = [
"parse-zoneinfo",
"phf",
"phf_codegen",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.17" version = "0.2.17"
@ -217,31 +116,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@ -252,12 +126,6 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "deunicode"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc55fe0d1f6c107595572ec8b107c0999bb1a2e0b75e37429a4fb0d6474a0e7d"
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.7" version = "0.10.7"
@ -326,47 +194,12 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.31.1" version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "globset"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "globwalk"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757"
dependencies = [
"bitflags",
"ignore",
"walkdir",
]
[[package]] [[package]]
name = "http" name = "http"
version = "1.3.1" version = "1.3.1"
@ -413,15 +246,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.6.0" version = "1.6.0"
@ -457,46 +281,6 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "iana-time-zone"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "ignore"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b"
dependencies = [
"crossbeam-deque",
"globset",
"log",
"memchr",
"regex-automata",
"same-file",
"walkdir",
"winapi-util",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.15"
@ -504,33 +288,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]] [[package]]
name = "js-sys" name = "json5"
version = "0.3.77" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
dependencies = [ dependencies = [
"once_cell", "pest",
"wasm-bindgen", "pest_derive",
"serde",
] ]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.171" version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libm"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.27" version = "0.4.27"
@ -575,15 +348,6 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.7" version = "0.36.7"
@ -599,15 +363,6 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "parse-zoneinfo"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24"
dependencies = [
"regex",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.1" version = "2.3.1"
@ -659,44 +414,6 @@ dependencies = [
"sha2", "sha2",
] ]
[[package]]
name = "phf"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [
"siphasher",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.16" version = "0.2.16"
@ -709,15 +426,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.94" version = "1.0.94"
@ -736,65 +444,6 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.24" version = "0.1.24"
@ -813,15 +462,6 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.219" version = "1.0.219"
@ -887,28 +527,6 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "siphasher"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "slug"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724"
dependencies = [
"deunicode",
"wasm-bindgen",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.14.0" version = "1.14.0"
@ -942,28 +560,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "tera"
version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee"
dependencies = [
"chrono",
"chrono-tz",
"globwalk",
"humansize",
"lazy_static",
"percent-encoding",
"pest",
"pest_derive",
"rand",
"regex",
"serde",
"serde_json",
"slug",
"unic-segment",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.12" version = "2.0.12"
@ -1070,56 +666,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unic-char-property"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
dependencies = [
"unic-char-range",
]
[[package]]
name = "unic-char-range"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
[[package]]
name = "unic-common"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
[[package]]
name = "unic-segment"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23"
dependencies = [
"unic-ucd-segment",
]
[[package]]
name = "unic-ucd-segment"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-version"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
dependencies = [
"unic-common",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.18" version = "1.0.18"
@ -1132,148 +678,12 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys",
]
[[package]]
name = "windows-core"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-result"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
@ -1352,26 +762,7 @@ name = "yyyi_ru"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"axum", "axum",
"tera", "json5",
"serde_json",
"tokio", "tokio",
] ]
[[package]]
name = "zerocopy"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -6,4 +6,5 @@ edition = "2024"
[dependencies] [dependencies]
axum = "0.8.3" axum = "0.8.3"
tokio = { version = "1.44.1", features = ["rt-multi-thread"] } tokio = { version = "1.44.1", features = ["rt-multi-thread"] }
tera="1.20.0" json5 = "0.4.1"
serde_json = "1.0.140"

View 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>.

View File

@ -0,0 +1,3 @@
Я Андреев Григорий ({{age}}),
живу в Москве, учусь прогать, люблю курить dwm и иногда пишу разного рода дичь.
Самым интересным в своей жизни делюсь <a href="/blog">вот здесь</a>.

View File

@ -1,20 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
{% import "lang_macro.html" as lang_macro %}
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<title>Гришина заглавная страничка</title> <title>{{pres.index.title}}</title>
</head> </head>
<body> <body>
<div class="main-container"> <div class="main-container">
<div> <div>
<h2 class=""> Обо мне </h2> <h2 class="">{{pres.index.about_me_header}}</h2>
<p class="description-text"> <p class="description-text">{% if aboutme_template is string %} STRING {{lang_macro::incl('aboutme/')}} {% else %} NOT STRING{%endif%}</p>
Я Андреев Григорий, от 21.06.2005.
Живу в Москве, учусь прогать, люблю курить dwm и иногда пишу разного рода дичь.
Самым интересным в своей жизни делюсь <a href="/blog">вот здесь</a>.
</p>
</div> </div>
</div> </div>
</body> </body>

View File

6
assets/text/en-US.json5 Normal file
View File

@ -0,0 +1,6 @@
{
index: {
title: "Gregory's title page",
about_me_header: "About me",
}
}

6
assets/text/ru-RU.json5 Normal file
View File

@ -0,0 +1,6 @@
{
index: {
title: "Гришина заглавная страничка",
about_me_header: "Обо мне",
}
}

View File

@ -1,2 +1,2 @@
pub mod yyyi_ru; pub mod yyyi_ru;
pub mod mtgott; pub mod mtgott;

27
src/mtgott/charclasses.rs Normal file
View 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("<", "&lt;").replace(">", "&gt;")
.replace("'", "&#39;").replace("\"", "&quot;")
}
pub fn is_illegal_name(s: &str) -> bool {
s != "_" && s != "if" && s != "else" && s != "for" && s != "let" && s != "self" && s != "super"
}

View File

@ -1,4 +1,386 @@
pub fn proclaim_glad_tidings() { mod charclasses;
println!("This project uses My Train Goes Off The Track!\n\
But I ain't writing this shit second time") 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 () {
}
}

View File

@ -5,10 +5,9 @@ use std::collections::HashMap;
use axum::http::HeaderValue; use axum::http::HeaderValue;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
use axum::http::header::CONTENT_TYPE; use axum::http;
use tera; use json5;
use serde_json;
use crate::mtgott::{proclaim_glad_tidings};
#[derive(Clone)] #[derive(Clone)]
struct StaticAsset { struct StaticAsset {
@ -18,9 +17,9 @@ struct StaticAsset {
#[derive(Clone)] #[derive(Clone)]
struct AssetsCache { struct AssetsCache {
page_index: StaticAsset, // templates: tera::Tera,
page_blog: StaticAsset, static_assets: HashMap<String, StaticAsset>,
static_assets: HashMap<String, StaticAsset> missing_text: Vec<(String, serde_json::Value)>
} }
struct ExtensionContentTypeCorr{ struct ExtensionContentTypeCorr{
@ -35,52 +34,70 @@ fn read_static_html_page(p: &Path) -> io::Result<StaticAsset> {
}) })
} }
impl AssetsCache { fn load_static_assets(p: &Path, need: &[ExtensionContentTypeCorr]) -> io::Result<HashMap<String, StaticAsset>> {
fn load(p: &Path, need: &[ExtensionContentTypeCorr]) -> Result<AssetsCache, io::Error> { if !p.is_dir() {
if !p.is_dir() { return Err(io::Error::from(io::ErrorKind::NotADirectory))
return Err(io::Error::from(io::ErrorKind::NotADirectory)) }
} let mut st: HashMap<String, StaticAsset> = HashMap::new();
let mut st: HashMap<String, StaticAsset> = HashMap::new(); let mut td: Vec<String> = vec![String::new()];
let mut td: Vec<String> = vec![String::new()]; while td.len() > 0 {
while td.len() > 0 { let dshp_dir: String = td.pop().unwrap();
let dshp_dir: String = td.pop().unwrap(); let p_dir = p.join(dshp_dir.clone());
let p_dir = p.join(dshp_dir.clone()); for entry in fs::read_dir(p_dir)? {
for entry in fs::read_dir(p_dir)? { let entry = entry?;
let entry = entry?; let dshp_child = if dshp_dir.len() > 0 {
let dshp_child = if dshp_dir.len() > 0 { format!("{dshp_dir}/{}", entry.file_name().to_str().unwrap())
format!("{dshp_dir}/{}", entry.file_name().to_str().unwrap()) } else {
} else { String::from(entry.file_name().to_str().unwrap())
String::from(entry.file_name().to_str().unwrap()) };
}; let p_child = p.join(dshp_child.clone());
let p_child = p.join(dshp_child.clone()); if p_child.is_dir() {
if p_child.is_dir() { td.push(dshp_child);
td.push(dshp_child); } else {
} else { if let Some(ext) = need.iter().find(|ext| {dshp_child.ends_with(ext.extension)}) {
if let Some(ext) = need.iter().find(|ext| {dshp_child.ends_with(ext.extension)}) { st.insert(dshp_child.clone(), StaticAsset {
st.insert(dshp_child.clone(), StaticAsset { content_type: ext.content_type.clone(),
content_type: ext.content_type.clone(), content: fs::read(p.join(dshp_child))?
content: fs::read(p.join(dshp_child))? });
});
}
} }
} }
} }
Ok(AssetsCache{
page_index: read_static_html_page(&p.join("HypertextPages/index.html"))?,
page_blog: read_static_html_page(&p.join("HypertextPages/blog.html"))?,
static_assets: st
})
} }
Ok(st)
} }
async fn page_index( fn load_needed_static_assets(p: &Path) -> io::Result<HashMap<String, StaticAsset>> {
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>> load_static_assets(p, &[
) -> impl axum::response::IntoResponse { ExtensionContentTypeCorr{extension: ".css", content_type: HeaderValue::from_str("text/css").unwrap()},
( ExtensionContentTypeCorr{extension: ".jpeg", content_type: HeaderValue::from_str("image/jpeg").unwrap()},
[(CONTENT_TYPE, assets.page_index.content_type.clone())], ExtensionContentTypeCorr{extension: ".jpg", content_type: HeaderValue::from_str("image/jpeg").unwrap()},
assets.page_index.content.clone() 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( async fn static_assets(
@ -89,18 +106,36 @@ async fn static_assets(
) -> Result<([(axum::http::HeaderName, axum::http::HeaderValue); 1], Vec<u8>), axum::http::StatusCode> { ) -> Result<([(axum::http::HeaderName, axum::http::HeaderValue); 1], Vec<u8>), axum::http::StatusCode> {
if let Some(file) = assets.static_assets.get(&path) { if let Some(file) = assets.static_assets.get(&path) {
return Ok(( return Ok((
[(CONTENT_TYPE, file.content_type.clone())], [(http::header::CONTENT_TYPE, file.content_type.clone())],
file.content.clone() file.content.clone()
)) ))
} }
Err(axum::http::StatusCode::NOT_FOUND) 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( async fn page_blog(
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>> axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>,
// axum::extract::Extension(t): axum::extract::Extension<tera::Tera>
) -> impl axum::response::IntoResponse { ) -> impl axum::response::IntoResponse {
axum::response::Html(String::from_utf8(assets.page_blog.content.clone()).unwrap()) // 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 { async fn fallback_page() -> axum::http::StatusCode {
@ -108,15 +143,10 @@ async fn fallback_page() -> axum::http::StatusCode {
} }
pub async fn MAIN() { pub async fn MAIN() {
let manifest_dir = env!("CARGO_MANIFEST_DIR"); let assets_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("assets");
println!("Cargo manifest dir: {manifest_dir}"); println!("Cargo manifest dir: {assets_dir:?}");
let static_assets_types: &[ExtensionContentTypeCorr] = &[
ExtensionContentTypeCorr{extension: "css", content_type: HeaderValue::from_str("text/css").unwrap()} let assets = Arc::new(load_assets(&assets_dir));
];
let assets = Arc::new(
AssetsCache::load(
&Path::new(manifest_dir).join("assets"),
static_assets_types).unwrap());
// build our application with a single route // build our application with a single route
let app = axum::Router::new() let app = axum::Router::new()
@ -125,6 +155,7 @@ pub async fn MAIN() {
.route("/assets/{*path}", axum::routing::get(static_assets)) .route("/assets/{*path}", axum::routing::get(static_assets))
.route("/blog", axum::routing::get(page_blog)) .route("/blog", axum::routing::get(page_blog))
.fallback(fallback_page).with_state(assets); .fallback(fallback_page).with_state(assets);
// .layer(axum::Extension(templates));
// run our app with hyper, listening globally on port 3000 // run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();