From acf9d3de9876b49a3ab3e80031f4009c6d22f44a Mon Sep 17 00:00:00 2001 From: heydocode <169077757+heydocode@users.noreply.github.com> Date: Sat, 9 Nov 2024 23:56:11 +0100 Subject: [PATCH 1/3] Major update to 1.0.0 --- .gitignore | 3 +- Cargo.lock | 2342 +++---------------------------- Cargo.toml | 3 +- screenshots/ServerAPI email.png | Bin 0 -> 20990 bytes src/file_reader.rs | 67 +- src/file_writer.rs | 5 +- src/mail.rs | 69 +- src/main.rs | 68 +- src/scheduler.rs | 52 +- src/setup.rs | 28 +- src/tests.rs | 105 +- 11 files changed, 474 insertions(+), 2268 deletions(-) create mode 100644 screenshots/ServerAPI email.png diff --git a/.gitignore b/.gitignore index 28f7917..1520227 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /target -/config -/config1 +/config \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 437d798..7f1fd4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,8 @@ version = "0.1.0" dependencies = [ "async-std", "lettre", - "rand 0.9.0-alpha.1", + "maud", "tracing-subscriber", - "valence", ] [[package]] @@ -28,17 +27,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - [[package]] name = "ahash" version = "0.8.11" @@ -46,19 +34,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", "once_cell", "version_check", - "zerocopy 0.7.34", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", + "zerocopy", ] [[package]] @@ -67,27 +45,6 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" -[[package]] -name = "android_log-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937" - -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" -dependencies = [ - "backtrace", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "async-channel" version = "1.9.0" @@ -230,17 +187,6 @@ version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" -[[package]] -name = "async-trait" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -268,261 +214,12 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bevy_app" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f557a7d59e1e16892d7544fc37316506ee598cb5310ef0365125a30783c11531" -dependencies = [ - "bevy_derive", - "bevy_ecs", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "downcast-rs", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "bevy_core" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d5272321be5fcf5ce2fb16023bc825bb10dfcb71611117296537181ce950f48" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_math", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "bytemuck", -] - -[[package]] -name = "bevy_derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44e4e2784a81430199e4157e02903a987a32127c773985506f020e7d501b62e" -dependencies = [ - "bevy_macro_utils", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "bevy_ecs" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266144b36df7e834d5198049e037ecdf2a2310a76ce39ed937d1b0a6a2c4e8c6" -dependencies = [ - "async-channel 1.9.0", - "bevy_ecs_macros", - "bevy_ptr", - "bevy_reflect", - "bevy_tasks", - "bevy_utils", - "downcast-rs", - "event-listener 2.5.3", - "fixedbitset", - "rustc-hash", - "serde", - "thiserror", - "thread_local", -] - -[[package]] -name = "bevy_ecs_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7157a9c3be038d5008ee3f114feb6cf6b39c1d3d32ee21a7cacb8f81fccdfa80" -dependencies = [ - "bevy_macro_utils", - "proc-macro2", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "bevy_hierarchy" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "103f8f58416ac6799b8c7f0b418f1fac9eba44fa924df3b0e16b09256b897e3d" -dependencies = [ - "bevy_app", - "bevy_core", - "bevy_ecs", - "bevy_log", - "bevy_reflect", - "bevy_utils", - "smallvec", -] - -[[package]] -name = "bevy_log" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07dcc615ff4f617b06c3f9522fca3c55d56f9644db293318f8ab68fcdea5d4fe" -dependencies = [ - "android_log-sys", - "bevy_app", - "bevy_ecs", - "bevy_utils", - "console_error_panic_hook", - "tracing-log 0.1.4", - "tracing-subscriber", - "tracing-wasm", -] - -[[package]] -name = "bevy_macro_utils" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ddc18d489b4e57832d4958cde7cd2f349f0ad91e5892ac9e2f2ee16546b981" -dependencies = [ - "quote", - "rustc-hash", - "syn 2.0.67", - "toml_edit", -] - -[[package]] -name = "bevy_math" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78286a81fead796dc4b45ab14f4f02fe29a94423d3587bcfef872b2a8e0a474b" -dependencies = [ - "glam 0.24.2", - "serde", -] - -[[package]] -name = "bevy_ptr" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c7586401a46f7d8e436028225c1df5288f2e0082d066b247a82466fea155c6" - -[[package]] -name = "bevy_reflect" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0778197a1eb3e095a71417c74b7152ede02975cdc95b5ea4ddc5251ed00a2eb5" -dependencies = [ - "bevy_math", - "bevy_ptr", - "bevy_reflect_derive", - "bevy_utils", - "downcast-rs", - "erased-serde", - "glam 0.24.2", - "once_cell", - "parking_lot", - "serde", - "smallvec", - "smol_str", - "thiserror", -] - -[[package]] -name = "bevy_reflect_derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342a4b2d09db22c48607d23ad59a056aff1ee004549050a51d490d375ba29528" -dependencies = [ - "bevy_macro_utils", - "bit-set", - "proc-macro2", - "quote", - "syn 2.0.67", - "uuid", -] - -[[package]] -name = "bevy_tasks" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c73bbb847c83990d3927005090df52f8ac49332e1643d2ad9aac3cd2974e66bf" -dependencies = [ - "async-channel 1.9.0", - "async-executor", - "async-task", - "concurrent-queue", - "futures-lite 1.13.0", - "wasm-bindgen-futures", -] - -[[package]] -name = "bevy_utils" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d9484e32434ea84dc548cff246ce0c6f756c1336f5ea03f24ac120a48595c7" -dependencies = [ - "ahash", - "bevy_utils_proc_macros", - "getrandom", - "hashbrown 0.14.5", - "instant", - "petgraph", - "thiserror", - "tracing", - "uuid", -] - -[[package]] -name = "bevy_utils_proc_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5391b242c36f556db01d5891444730c83aa9dd648b6a8fd2b755d22cb3bddb57" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitfield-struct" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e766e50a6ec4582ebf04c907ac902e598fa295db078b5fdc71cd1efb0557e1" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -535,15 +232,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" -[[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 = "blocking" version = "1.6.1" @@ -563,45 +251,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "bytemuck" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" - [[package]] name = "cc" version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfb8" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "014c0a0e1ad0dae6a86c082db2f9bd7fe8c2c734227047d0d8b4d4a3a094a1e1" -dependencies = [ - "cipher", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -614,20 +269,10 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ - "hashbrown 0.14.5", + "hashbrown", "stacker", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -637,22 +282,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - [[package]] name = "core-foundation" version = "0.9.4" @@ -669,85 +298,19 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-utils" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" -[[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 = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - [[package]] name = "email-encoding" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60d1d33cdaede7e24091f039632eb5d3c7469fe5b066a985281a34fc70fa317f" dependencies = [ - "base64 0.22.1", + "base64", "memchr", ] @@ -757,30 +320,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - [[package]] name = "errno" version = "0.3.9" @@ -834,47 +373,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flate2" -version = "1.0.30" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", + "foreign-types-shared", ] [[package]] @@ -941,12 +445,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - [[package]] name = "futures-task" version = "0.3.30" @@ -968,51 +466,12 @@ dependencies = [ "slab", ] -[[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 = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - [[package]] name = "gimli" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" -[[package]] -name = "glam" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" - -[[package]] -name = "glam" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" -dependencies = [ - "bytemuck", - "serde", -] - [[package]] name = "gloo-timers" version = "0.2.6" @@ -1025,40 +484,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.14.5" @@ -1067,15 +492,8 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", - "serde", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "hermit-abi" version = "0.3.9" @@ -1088,15 +506,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - [[package]] name = "hostname" version = "0.4.0" @@ -1108,78 +517,12 @@ dependencies = [ "windows", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - [[package]] name = "httpdate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.7", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - [[package]] name = "idna" version = "0.5.0" @@ -1190,36 +533,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - [[package]] name = "instant" version = "0.1.13" @@ -1227,9 +540,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -1243,12 +553,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - [[package]] name = "itoa" version = "1.0.11" @@ -1278,9 +582,6 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] [[package]] name = "lettre" @@ -1288,7 +589,7 @@ version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a62049a808f1c4e2356a2a380bd5f2aca3b011b0b482cf3b914ba1731426969" dependencies = [ - "base64 0.22.1", + "base64", "chumsky", "email-encoding", "email_address", @@ -1313,12 +614,6 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -1331,16 +626,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.21" @@ -1351,21 +636,25 @@ dependencies = [ ] [[package]] -name = "lru" -version = "0.10.1" +name = "maud" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +checksum = "df518b75016b4289cdddffa1b01f2122f4a49802c93191f3133f6dc2472ebcaa" dependencies = [ - "hashbrown 0.13.2", + "itoa", + "maud_macros", ] [[package]] -name = "matchers" -version = "0.1.0" +name = "maud_macros" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "fa453238ec218da0af6b11fc5978d3b5c3a45ed97b722391a2a11f3306274e18" dependencies = [ - "regex-automata 0.1.10", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1406,15 +695,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - [[package]] name = "native-tls" version = "0.2.12" @@ -1452,79 +732,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - [[package]] name = "object" version = "0.36.0" @@ -1563,7 +770,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn", ] [[package]] @@ -1596,80 +803,12 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.5", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pem-rfc7468" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap 2.2.6", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1693,28 +832,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pkcs1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" -dependencies = [ - "der", - "pkcs8", - "spki", - "zeroize", -] - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der", - "spki", -] - [[package]] name = "pkg-config" version = "0.3.30" @@ -1747,1319 +864,326 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.34", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "psm" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" -dependencies = [ - "cc", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "quoted_printable" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.0-alpha.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31e63ea85be51c423e52ba8f2e68a3efd53eed30203ee029dd09947333693e" -dependencies = [ - "rand_chacha 0.9.0-alpha.1", - "rand_core 0.9.0-alpha.1", - "zerocopy 0.8.0-alpha.6", -] - -[[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 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0-alpha.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78674ef918c19451dbd250f8201f8619b494f64c9aa6f3adb28fd8a0f1f6da46" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.0-alpha.1", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_core" -version = "0.9.0-alpha.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc89dffba8377c5ec847d12bb41492bda235dba31a25e8b695cd0fe6589eb8c9" -dependencies = [ - "getrandom", - "zerocopy 0.8.0-alpha.6", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" -dependencies = [ - "bitflags 2.5.0", -] - -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rsa" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" -dependencies = [ - "byteorder", - "digest", - "num-bigint-dig", - "num-integer", - "num-iter", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "smallvec", - "subtle", - "zeroize", -] - -[[package]] -name = "rsa-der" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19473b2de3164677ff38e4309c42448ba8d0fe5ad5fa722e7d278f991859aa6" -dependencies = [ - "simple_asn1", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.37.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys 0.4.14", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "security-framework" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" -dependencies = [ - "bitflags 2.5.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "serde_json" -version = "1.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[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 = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -dependencies = [ - "serde", -] - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "stacker" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" -dependencies = [ - "cc", - "cfg-if", - "libc", - "psm", - "winapi", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand 2.1.0", - "rustix 0.38.34", - "windows-sys 0.52.0", -] - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.5.7", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log 0.2.0", -] - -[[package]] -name = "tracing-wasm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" -dependencies = [ + "rustix 0.38.34", "tracing", - "tracing-subscriber", - "wasm-bindgen", + "windows-sys 0.52.0", ] [[package]] -name = "try-lock" -version = "0.2.5" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] [[package]] -name = "typenum" -version = "1.17.0" +name = "proc-macro-error-attr" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "proc-macro2" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "psm" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] [[package]] -name = "unicode-normalization" -version = "0.1.23" +name = "quote" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "tinyvec", + "proc-macro2", ] [[package]] -name = "untrusted" -version = "0.9.0" +name = "quoted_printable" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" [[package]] -name = "url" -version = "2.5.2" +name = "rustc-demangle" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] -name = "uuid" -version = "1.9.1" +name = "rustix" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ - "getrandom", - "serde", + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", ] [[package]] -name = "valence" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "rustix" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69539512d4dac7ef2528472f3d43f7964f0fb33ab31a09f07c60c3c4c80745f" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "anyhow", - "bevy_app", - "bevy_ecs", - "bevy_log", - "bytes", - "rand 0.8.5", - "uuid", - "valence_advancement", - "valence_anvil", - "valence_boss_bar", - "valence_ident", - "valence_inventory", - "valence_lang", - "valence_network", - "valence_player_list", - "valence_registry", - "valence_scoreboard", - "valence_server", - "valence_text", - "valence_weather", - "valence_world_border", + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", ] [[package]] -name = "valence_advancement" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "schannel" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d500048f5a907593c504422115e655f952aa4523f9cc0f35d05a96558d279546" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "bevy_app", - "bevy_ecs", - "bevy_hierarchy", - "rustc-hash", - "valence_server", + "windows-sys 0.52.0", ] [[package]] -name = "valence_anvil" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "security-framework" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5306fac3ce3e34d1a058d08fa005fde3768c110c2075dfbb6fe056f1ecd55e2e" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bevy_app", - "bevy_ecs", - "byteorder", - "flate2", - "flume", - "lru", - "num-integer", - "thiserror", - "tracing", - "valence_server", + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", ] [[package]] -name = "valence_boss_bar" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "security-framework-sys" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6a93e7cdcb49f0d97216a66d6de9825cedac7821b1b3eb823d90cbb831dbb67" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ - "bevy_app", - "bevy_ecs", - "bitfield-struct", - "valence_entity", - "valence_server", + "core-foundation-sys", + "libc", ] [[package]] -name = "valence_build_utils" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce1ae18bd4f96ff2049b1119ea2ec5617990e6e5ce06187450c3c7000bfb9bc" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "anyhow", - "proc-macro2", - "syn 2.0.67", + "lazy_static", ] [[package]] -name = "valence_entity" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7623ee12f1d772413f0a7a36bec007177a506ae81d1e22d8c54db3a68710f6b9" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "anyhow", - "bevy_app", - "bevy_ecs", - "bitfield-struct", - "heck", - "paste", - "proc-macro2", - "quote", - "rustc-hash", - "serde", - "serde_json", - "syn 2.0.67", - "tracing", - "uuid", - "valence_build_utils", - "valence_math", - "valence_nbt", - "valence_protocol", - "valence_server_common", + "autocfg", ] [[package]] -name = "valence_generated" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "smallvec" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8028e12211fb6e6470b32f54c6ebe9df8928691e1b27d7f3b84c82a6c9031a40" -dependencies = [ - "anyhow", - "heck", - "proc-macro2", - "quote", - "serde", - "serde_json", - "valence_build_utils", - "valence_ident", - "valence_math", -] +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "valence_ident" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "socket2" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c75f5991893b0661e27e1f7f51b88a72c68a7aee46dc8ab50710cfa86167bd0" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ - "serde", - "thiserror", - "valence_ident_macros", + "libc", + "winapi", ] [[package]] -name = "valence_ident_macros" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "socket2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0f21404a1d14bb4c99c41355bf14b527b0116e69adbc06b91b4a9c1e61bd38" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "valence_inventory" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "stacker" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fabc7b492579eb012fedf9e3e00ed4cecf1f94fa0268aac7f0a36bc17f28c6c" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" dependencies = [ - "bevy_app", - "bevy_ecs", - "tracing", - "valence_server", + "cc", + "cfg-if", + "libc", + "psm", + "winapi", ] [[package]] -name = "valence_lang" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "syn" +version = "2.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8957429668e87e92c3cfd4af5d8a887ab3e5a18fe75d9083e128b57e541a7f7b" +checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" dependencies = [ - "anyhow", - "heck", "proc-macro2", "quote", - "serde", - "serde_json", - "valence_build_utils", + "unicode-ident", ] [[package]] -name = "valence_math" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tempfile" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db591a83da1167f0957db4794c9b5eaa30f9c0cd39a684d06b1d16c7bb30c130" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ - "glam 0.23.0", + "cfg-if", + "fastrand 2.1.0", + "rustix 0.38.34", + "windows-sys 0.52.0", ] [[package]] -name = "valence_nbt" -version = "0.6.1" +name = "thread_local" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d8921a6ebbb93ddbcd0e152611bd94fb928199efe8528077ab36787b298be4" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "byteorder", - "cesu8", - "indexmap 1.9.3", - "serde", - "thiserror", - "uuid", + "cfg-if", + "once_cell", ] [[package]] -name = "valence_network" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tinyvec" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b31cde2e3178f2d3167a8fb0bd74120804a7f43655f308a1eac56f81ff22dee" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ - "anyhow", - "async-trait", - "base64 0.21.7", - "bevy_app", - "bevy_ecs", - "bytes", - "flume", - "hmac", - "num-bigint", - "rand 0.8.5", - "reqwest", - "rsa", - "rsa-der", - "serde", - "serde_json", - "sha1", - "sha2", - "thiserror", - "tokio", - "tracing", - "uuid", - "valence_lang", - "valence_protocol", - "valence_server", + "tinyvec_macros", ] [[package]] -name = "valence_player_list" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165dca30d8621a355e37582688f206e5e97d5b577d9867ae682750991a8d639e" -dependencies = [ - "bevy_app", - "bevy_ecs", - "bitfield-struct", - "valence_server", -] +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "valence_protocol" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tokio" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db702fdbaf978d864f7a0dc965ed67311878a047125c6613dfcb0faf090f5c5e" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ - "aes", - "anyhow", - "base64 0.21.7", - "bevy_ecs", - "bitfield-struct", - "byteorder", - "bytes", - "cfb8", - "flate2", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "uuid", - "valence_generated", - "valence_ident", - "valence_math", - "valence_nbt", - "valence_protocol_macros", - "valence_text", + "backtrace", + "libc", + "mio", + "pin-project-lite", + "socket2 0.5.7", + "windows-sys 0.48.0", ] [[package]] -name = "valence_protocol_macros" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tracing" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683f94d8f0b0d5fa724509d35c74718a67d6e6b8747a3e83f095121d4abf8b4a" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", + "pin-project-lite", + "tracing-core", ] [[package]] -name = "valence_registry" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tracing-core" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00970d83f890a93d2de62f51b46fb592aa3ea9693ae51cbc9662b6c3b0b36b8c" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "anyhow", - "bevy_app", - "bevy_ecs", - "indexmap 1.9.3", - "serde", - "serde_json", - "tracing", - "valence_ident", - "valence_nbt", - "valence_protocol", - "valence_server_common", + "once_cell", + "valuable", ] [[package]] -name = "valence_scoreboard" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c64ea00285580e0d8b1a105b7d59116c4de5887bb4fa645336395765db058f8" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "bevy_app", - "bevy_ecs", - "tracing", - "valence_server", + "log", + "once_cell", + "tracing-core", ] [[package]] -name = "valence_server" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "tracing-subscriber" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a011cf9b587d89bd667225e0f3e14d1466fb7fead06d7860831e26638acf1845" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ - "anyhow", - "arrayvec", - "bevy_app", - "bevy_ecs", - "bevy_utils", - "bitfield-struct", - "byteorder", - "bytes", - "num-integer", - "parking_lot", - "rand 0.8.5", - "rustc-hash", - "tracing", - "uuid", - "valence_entity", - "valence_generated", - "valence_math", - "valence_nbt", - "valence_protocol", - "valence_registry", - "valence_server_common", + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] -name = "valence_server_common" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "unicode-bidi" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63a7ab950bc2b6e615cb40371e29e35868ffd58d14f487f109f1637b890a7be8" -dependencies = [ - "bevy_app", - "bevy_ecs", - "rand 0.8.5", - "uuid", - "valence_protocol", -] +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] -name = "valence_text" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d2d372465d6333fc5b73a5abb4f487bf36568860415462cc9cb5eb88f32eb5" -dependencies = [ - "anyhow", - "serde", - "serde_json", - "thiserror", - "uuid", - "valence_ident", - "valence_nbt", -] +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "valence_weather" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "unicode-normalization" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "505e17a656cd4f00e855fad4fb4422b4b8226ee71f129927d9a587d19ba1e23c" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ - "bevy_app", - "bevy_ecs", - "valence_server", + "tinyvec", ] [[package]] -name = "valence_world_border" -version = "0.2.0-alpha.1+mc.1.20.1" +name = "url" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545ecc16db455781a101035454b9503dcd8ea540e2a92b964dc40fd12acd15bd" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ - "bevy_app", - "bevy_ecs", - "valence_server", + "form_urlencoded", + "idna", + "percent-encoding", ] [[package]] @@ -3092,15 +1216,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3128,7 +1243,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.67", + "syn", "wasm-bindgen-shared", ] @@ -3162,7 +1277,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3183,12 +1298,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "winapi" version = "0.3.9" @@ -3369,41 +1478,13 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "zerocopy" version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ - "zerocopy-derive 0.7.34", -] - -[[package]] -name = "zerocopy" -version = "0.8.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db678a6ee512bd06adf35c35be471cae2f9c82a5aed2b5d15e03628c98bddd57" -dependencies = [ - "zerocopy-derive 0.8.0-alpha.6", + "zerocopy-derive", ] [[package]] @@ -3414,22 +1495,5 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201585ea96d37ee69f2ac769925ca57160cef31acb137c16f38b02b76f4c1e62" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.67", + "syn", ] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index 2a792e8..154ae94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,5 @@ edition = "2021" [dependencies] async-std = "1.12.0" lettre = "0.11" +maud = "0.26.0" tracing-subscriber = "0.3.18" -rand = "0.9.0-alpha.1" -valence = "0.2.0-alpha.1" diff --git a/screenshots/ServerAPI email.png b/screenshots/ServerAPI email.png new file mode 100644 index 0000000000000000000000000000000000000000..fa0751bbd32181f0ead2ad3d513754e8e6e18414 GIT binary patch literal 20990 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 literal 0 HcmV?d00001 diff --git a/src/file_reader.rs b/src/file_reader.rs index 91c990d..7e937d2 100644 --- a/src/file_reader.rs +++ b/src/file_reader.rs @@ -1,46 +1,73 @@ -use std::fs::File; -use std::io::BufReader; -use std::io::prelude::*; +use std::fs::{create_dir_all, File, metadata}; +use std::io::{BufReader, Read}; +use std::path::Path; pub fn smtp_account_reader() -> Result, String> { let file_path = "config/smtp_account.txt"; - - let contents = read_from_file(file_path); - let lines = contents.split_whitespace(); + let contents = read_from_file(file_path)?; + let lines = contents.lines(); let mut i = 0; let mut res: Vec = vec![]; - if contents.len() <= 10 { - return Err(String::from("The file is empty!")); + if contents.lines().count() < 2 { + return Err(String::from("Contents does not have enough lines")); } for line in lines { i += 1; if i == 1 { res.push(line.replace("username:", "")); - } - else if i == 2 { + } else if i == 2 { res.push(line.replace("password:", "")); + } else if i == 3 { + res.push(line.replace("receiver:", "")); } } Ok(res) } pub fn mc_status_reader() -> String { - let file_path = "config/logs.txt"; - let contents = read_from_file(file_path); - if contents.len() <= 5 { - String::from("The server's logs are empty! Is there a problem?") + let file_path = Path::new("config/logs.txt"); + let file_dir = Path::new("config"); + + if !file_path.exists() { + // Try to create the directory and file if they don't exist + if let Err(e) = create_dir_all(file_dir) { + return format!("Unable to create directory: {}", e); + } + if let Err(e) = File::create(file_path) { + return format!("Unable to create file: {}", e); + } } - else { - contents + + let contents = read_from_file(file_path.to_str().unwrap_or("config/logs.txt")); + if contents.clone().expect("Could not convert contents to Ok()").len() <= 5 { + String::from("The server's logs are empty! Is there a problem?") + } else { + contents.expect("Could not convert contents to Ok()") } } -fn read_from_file(file_path: &str) -> String { - let file = File::open(file_path).expect("An error occurs when tried to open a file"); +fn read_from_file(file_path: &str) -> Result { + // Debug feature to show metadata information + #[cfg(debug_assertions)] + { + match metadata(file_path) { + Ok(meta) => { + println!("File metadata for '{}':", file_path); + println!(" Size: {} bytes", meta.len()); + println!(" Permissions: {:?}", meta.permissions()); + } + Err(e) => eprintln!("Failed to retrieve file metadata: {}", e), + } + } + + // Attempt to open the file + let file = File::open(file_path).map_err(|e| format!("Error opening file '{}': {}", file_path, e))?; let mut buf_reader = BufReader::new(file); let mut contents = String::new(); - buf_reader.read_to_string(&mut contents).expect("An error occurs when tried to read the file"); - contents + + buf_reader.read_to_string(&mut contents).map_err(|e| format!("Error reading file '{}': {}", file_path, e))?; + + Ok(contents) } diff --git a/src/file_writer.rs b/src/file_writer.rs index 3752f16..c648927 100644 --- a/src/file_writer.rs +++ b/src/file_writer.rs @@ -14,7 +14,7 @@ pub async fn write_to_file(text: String, file_path: &str) -> Result<(), String> file.write_all(text.as_bytes()).await.map_err(|e| e.to_string()) } -pub async fn update_credentials(username: String, password: String) -> Result<(), String> { +pub async fn update_credentials(username: String, password: String, receiver: String) -> Result<(), String> { let file_path = "config/smtp_account.txt"; let path = Path::new(file_path); @@ -30,7 +30,8 @@ pub async fn update_credentials(username: String, password: String) -> Result<() let updated_content = content .replace("username:example@gmail.com", &format!("username:{}", username)) - .replace("password:password123123", &format!("password:{}", password)); + .replace("password:password123123", &format!("password:{}", password)) + .replace("receiver:example@gmail.com", &format!("receiver:{}", receiver)); { let mut file = OpenOptions::new() diff --git a/src/mail.rs b/src/mail.rs index 77600e3..3923bf4 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -1,22 +1,43 @@ +use crate::file_reader::smtp_account_reader; +use crate::file_writer::write_to_file; use lettre::{ - message::header::ContentType, transport::smtp::authentication::Credentials, Message, + message::{header::{self, ContentType}, MultiPart, SinglePart}, transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport, }; -use crate::file_reader::smtp_account_reader; -use crate::file_writer::write_to_file; +use maud::PreEscaped; + +pub async fn mail_sender(title: &str, html: PreEscaped) { + let res: Vec = + smtp_account_reader().expect("Could not assign smtp_account_reader output to vector res"); + let username = &res[0]; + let password = &res[1]; + let receiver = &res[2]; -pub async fn mail_sender(title: &str, text: String) { let email = Message::builder() - .from("ServerAPI ".parse().expect("Error parsing sender in Message Builder")) - // .reply_to("Yuin ".parse().unwrap()) - .to("Nick ".parse().expect("Error parsing receiver in Message Builder")) + .from( + username + .parse() + .expect("Error parsing sender in Message Builder"), + ) + .to(receiver + .parse() + .expect("Error parsing receiver in Message Builder")) .subject(title) - .header(ContentType::TEXT_PLAIN) - .body(text) + .multipart( + MultiPart::alternative() + .singlepart( + SinglePart::builder() + .header(header::ContentType::TEXT_PLAIN) + .body(format!( + "Hello there!\nYour server is working fine! The next status email will be sent in 5 minutes.\n\nServer's Logs:\nYour client does not support html...")), + ) + .singlepart( + SinglePart::builder() + .header(header::ContentType::TEXT_HTML) + .body(html.into_string()), + ), + ) .unwrap(); - let res: Vec = smtp_account_reader().expect("Could not assign smtp_account_reader output to vector res"); - let username = &res[0]; - let password = &res[1]; let creds = Credentials::new((username).to_owned(), password.to_owned()); // Open a remote connection to gmail using STARTTLS @@ -28,16 +49,26 @@ pub async fn mail_sender(title: &str, text: String) { // Send the email match mailer.send(&email) { Ok(_) => { - match write_to_file(format!("Email has been sent successfully!"), "config/mail_logs.txt").await { - Ok(()) => {}, - n => println!("An error occured when tried to write logs (email success): {n:?}") + match write_to_file( + format!("Email has been sent successfully!"), + "config/mail_logs.txt", + ) + .await + { + Ok(()) => {} + n => println!("An error occured when tried to write logs (email success): {n:?}"), } println!("Email has been sent successfully!"); - }, + } Err(e) => { - match write_to_file(format!("Could not send email: {e:?}"), "config/mail_logs.txt").await { - Ok(()) => {}, - n => println!("An error occured when tried to write logs (email failure): {n:?}") + match write_to_file( + format!("Could not send email: {e:?}"), + "config/mail_logs.txt", + ) + .await + { + Ok(()) => {} + n => println!("An error occured when tried to write logs (email failure): {n:?}"), } panic!("Could not send email: {e:?}"); } diff --git a/src/main.rs b/src/main.rs index 62164d9..3978d85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -mod mail; mod file_reader; mod file_writer; +mod mail; mod scheduler; // mod mc_server; mod setup; @@ -17,34 +17,50 @@ use tracing_subscriber; fn main() { tracing_subscriber::fmt::init(); - let setup_handle = thread::Builder::new().name("setup".to_string()).spawn(|| async { + let setup_handle = thread::Builder::new().name("setup".to_string()).spawn(|| { + println!("Setup Process has been launched"); match check_config_components() { - Ok(()) => {}, - n => println!("An error occured when tried to check config components: {n:?}") + Ok(()) => {} + n => println!("An error occured when tried to check config components: {n:?}"), } - match write_to_file(format!("All config components are OK, loading the server.."), "config/logs.txt").await { - Ok(()) => {}, - n => println!("An error occured when tried to write logs (setup success): {n:?}") - } - }); - - setup_handle.expect("Unable to join setup handle").join().unwrap(); - println!("All config components are OK, loading the server.."); -/* - let mc_handle = thread::Builder::new().name("mc_server".to_string()).spawn(|| { - println!("MC Server has been enabled"); - start_mc_server(); - println!("MC Server has been disabled"); + async_std::task::block_on(async { + match write_to_file( + format!("All config components are OK, loading the server.."), + "config/logs.txt", + ) + .await + { + Ok(()) => {} + n => println!("An error occured when tried to write logs (setup success): {n:?}"), + } + }); }); -*/ - let mail_handle = thread::Builder::new().name("mail_server".to_string()).spawn(|| { - println!("Mail Server has been enabled"); - status_upload(); - println!("Mail Server has been disabled"); - }); - - mail_handle.expect("Unable to join mail server handle").join().unwrap(); - // mc_handle.expect("Unable to join mc server handle").join().unwrap(); + if let Err(_) = setup_handle.expect("Unable to join setup handle").join() { + eprintln!("An error occured when tried to join setup handle"); + } else { + let mail_handle = thread::Builder::new() + .name("mail_server".to_string()) + .spawn(|| { + println!("Mail Server has been enabled"); + status_upload(); + println!("Mail Server has been disabled"); + }); + if let Err(_) = mail_handle.expect("Unable to join mail handle").join() { + eprintln!("An error occured when tried to join mail handle"); + } + // Please consider adding `else if` blocks until all handles won't be joined + else { + println!("All config components are OK, loading the server.."); + } + } + /* + MINECRAFT SERVER SUPPORT USING VALENCE + let mc_handle = thread::Builder::new().name("mc_server".to_string()).spawn(|| { + println!("MC Server has been enabled"); + start_mc_server(); + println!("MC Server has been disabled"); + }); + */ } diff --git a/src/scheduler.rs b/src/scheduler.rs index c7108ed..2dab44e 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -1,34 +1,56 @@ -use crate::mail::mail_sender; +use maud::html; + use crate::file_reader::mc_status_reader; +use crate::mail::mail_sender; -use async_std::task; -use std::time::Instant; use std::time::Duration; +use std::time::Instant; pub fn status_upload() { let mut start = Instant::now(); - let mut i: u128 = 1; + let mut i: u16 = 1; loop { let elapsed = start.elapsed(); if elapsed > Duration::new(60 * 5, 0) || i == 1 { - let text = format!(" - Hello there! - Your server is working fine! Next status email will be sended in 5 minutes! - With technical love, ServerAPI :) + let html = html! { + head { + title { "Server Status Update from ServerAPI" } + } + body style="font-family: Arial, Helvetica, sans-serif; color: #333; background-color: #f9f9f9; padding: 20px;" { + div style="max-width: 600px; margin: auto; background: #ffffff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);" { + h2 style="color: #4CAF50;" { "Server Status Update" } + p { "Hello there!" } + p { + "Your server is working fine! The next status email will be sent in 5 minutes." + br; + "With technical love, ServerAPI :)" + } + + // Logs section with preformatted content for server logs + h3 style="color: #4CAF50;" { "Server Logs" } + pre style="background-color: #f4f4f4; padding: 10px; border-radius: 5px; white-space: pre-wrap; font-family: monospace; color: #333;" { + (mc_status_reader()) + } - Server's logs:\n{:?} - ", mc_status_reader()); + // Footer message with link + p style="font-size: 12px; color: #666; text-align: center; margin-top: 20px;" { + "This email was automatically generated by " + a href="https://github.com/heydocode/ServerAPI" style="color: #4CAF50; text-decoration: none;" { "ServerAPI" } + ". Please do not reply." + } + } + } + }; let title = "STATUS Email"; - task::spawn(async move { - mail_sender(title, text); + async_std::task::block_on(async move { + mail_sender(title, html).await; }); start = Instant::now(); - if i > u128::MAX - 10 { + if i > u16::MAX - 10 { i = 2; - } - else { + } else { i += 1; } } diff --git a/src/setup.rs b/src/setup.rs index dc3529e..dffa194 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -32,7 +32,7 @@ pub fn check_config_components() -> std::result::Result<(), String> { if path == Path::new("config/smtp_account.txt") { match smtp_account_reader() { Err(_) => { - let _ = write!(file, "username:example@gmail.com\npassword:password123123\n\n### The username is your gmail account (example@gmail.com)\n### The password is a 'password for apps' created in Google\n## NOTICE: To create an app-password, you have to have 2-step verification\n## enabled and maybe all rescue options of saving the account.").map_err(|e| e.to_string()); + let _ = write!(file, "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n\n### The username is your gmail account (example@gmail.com)\n### The password is a 'password for apps' created in Google\n## NOTICE: To create an app-password, you have to have 2-step verification\n## enabled and maybe all rescue options of saving the account.").map_err(|e| e.to_string()); setup_wizard(); }, _ => {} @@ -46,6 +46,7 @@ pub fn setup_wizard() { let mut iter: u8 = 1; let mut smtp_account_username = String::new(); let mut smtp_account_password = String::new(); + let mut receiver_gmail = String::new(); loop { match iter { @@ -61,6 +62,12 @@ pub fn setup_wizard() { 4 => { println!("Can you confirm your smtp account password (Y or N)?"); }, + 5 => { + println!("Enter your gmail account as a receiver\n(you will receive status emails on this gmail address):") + } + 6 => { + println!("Can you confirm your gmail account username (Y or N)?"); + } _ => () } let input = read_line(); @@ -90,9 +97,26 @@ pub fn setup_wizard() { else { iter = 3 } + }, + 5 => { + println!("You have entered \"{}\" as your gmail account username", input); + receiver_gmail = input.clone(); + iter += 1; + } + 6 => { + if input.to_lowercase() == "y" { + iter += 1; + } + else { + iter = 5 + } } _ => { - update_credentials(smtp_account_username, smtp_account_password); + async_std::task::block_on(async move { + update_credentials(smtp_account_username, smtp_account_password, receiver_gmail) + .await + .expect("Failed to update credentials"); + }); return; } } diff --git a/src/tests.rs b/src/tests.rs index 170fa1d..0ac9b9f 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,63 +1,86 @@ #[cfg(test)] mod tests { use crate::*; + use async_std::fs::{self, File}; use async_std::path::Path; use async_std::prelude::*; - use async_std::fs::{self, File, OpenOptions}; - use async_std::task; + use file_writer::update_credentials; - #[async_std::test] - async fn test_write_to_file() { + #[test] + fn test_write_to_file() { let test_file_path = "test_write_to_file.txt"; - // Ensure the test file is clean - if Path::new(test_file_path).exists().await { - fs::remove_file(test_file_path).await.expect("Failed to remove test file"); - } + // Use block_on to run the async code inside the test + async_std::task::block_on(async { + // Ensure the test file is clean + if Path::new(test_file_path).exists().await { + fs::remove_file(test_file_path) + .await + .expect("Failed to remove test file"); + } - // Write to the file - write_to_file("Hello, world!".to_string(), test_file_path) - .await - .expect("Failed to write to file"); + // Write to the file + write_to_file("Hello, world!".to_string(), test_file_path) + .await + .expect("Failed to write to file"); - // Read the file content - let mut file = File::open(test_file_path).await.expect("Failed to open test file"); - let mut content = String::new(); - file.read_to_string(&mut content).await.expect("Failed to read test file"); + // Read the file content + let mut file = File::open(test_file_path) + .await + .expect("Failed to open test file"); + let mut content = String::new(); + file.read_to_string(&mut content) + .await + .expect("Failed to read test file"); - // Check the content - assert_eq!(content, "Hello, world!"); + // Check the content + assert_eq!(content, "Hello, world!"); - // Clean up - fs::remove_file(test_file_path).await.expect("Failed to remove test file"); + // Clean up + fs::remove_file(test_file_path) + .await + .expect("Failed to remove test file"); + }); } - #[async_std::test] - async fn test_update_credentials() { + #[test] + fn test_update_credentials() { let test_file_path = "config/test_smtp_account.txt"; - // Ensure the config directory exists - fs::create_dir_all("config").await.expect("Failed to create config directory"); + // Use block_on to run the async code inside the test + async_std::task::block_on(async { + // Ensure the config directory exists + fs::create_dir_all("config") + .await + .expect("Failed to create config directory"); - // Prepare the test file - let initial_content = "username:example@gmail.com\npassword:password123123\n"; - fs::write(test_file_path, initial_content).await.expect("Failed to write initial content"); + // Prepare the test file + let initial_content = "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n"; + fs::write(test_file_path, initial_content) + .await + .expect("Failed to write initial content"); - // Update credentials - update_credentials("new_username".to_string(), "new_password".to_string()) - .await - .expect("Failed to update credentials"); + // Update credentials + update_credentials("new_username".to_string(), "new_password".to_string(), "examplereceiver".to_string()) + .await + .expect("Failed to update credentials"); + // Read the updated file content + let mut file = File::open(test_file_path) + .await + .expect("Failed to open test file"); + let mut content = String::new(); + file.read_to_string(&mut content) + .await + .expect("Failed to read test file"); - // Read the updated file content - let mut file = File::open(test_file_path).await.expect("Failed to open test file"); - let mut content = String::new(); - file.read_to_string(&mut content).await.expect("Failed to read test file"); + // Check the updated content + let expected_content = "username:new_username\npassword:new_password\nreceiver:example_receiver\n"; + assert_eq!(content, expected_content); - // Check the updated content - let expected_content = "username:new_username\npassword:new_password\n"; - assert_eq!(content, expected_content); - - // Clean up - fs::remove_file(test_file_path).await.expect("Failed to remove test file"); + // Clean up + fs::remove_file(test_file_path) + .await + .expect("Failed to remove test file"); + }); } } From af31e6ec25a8a02ee2f9dbb761eea4c81a5ca2e1 Mon Sep 17 00:00:00 2001 From: heydocode <169077757+heydocode@users.noreply.github.com> Date: Sun, 10 Nov 2024 00:15:16 +0100 Subject: [PATCH 2/3] fmt & enhancements & changelog --- Cargo.lock | 83 ------------------------- Cargo.toml | 1 - changelog/1.0.0.md | 18 ++++++ src/file_reader.rs | 18 ++++-- src/file_writer.rs | 26 +++++--- src/mail.rs | 12 ++-- src/main.rs | 44 ++++++++------ src/setup.rs | 74 +++++++++++++---------- src/tests.rs | 148 +++++++++++++++++++++++---------------------- 9 files changed, 197 insertions(+), 227 deletions(-) create mode 100644 changelog/1.0.0.md diff --git a/Cargo.lock b/Cargo.lock index 7f1fd4a..c65bdc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,7 +9,6 @@ dependencies = [ "async-std", "lettre", "maud", - "tracing-subscriber", ] [[package]] @@ -577,12 +576,6 @@ dependencies = [ "log", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "lettre" version = "0.11.7" @@ -722,16 +715,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "object" version = "0.36.0" @@ -791,12 +774,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "parking" version = "2.2.0" @@ -990,15 +967,6 @@ dependencies = [ "libc", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "slab" version = "0.4.9" @@ -1008,12 +976,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - [[package]] name = "socket2" version = "0.4.10" @@ -1070,16 +1032,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -1124,35 +1076,6 @@ name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "nu-ansi-term", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", -] [[package]] name = "unicode-bidi" @@ -1186,12 +1109,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "value-bag" version = "1.9.0" diff --git a/Cargo.toml b/Cargo.toml index 154ae94..c2ee999 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,3 @@ edition = "2021" async-std = "1.12.0" lettre = "0.11" maud = "0.26.0" -tracing-subscriber = "0.3.18" diff --git a/changelog/1.0.0.md b/changelog/1.0.0.md new file mode 100644 index 0000000..0046ee2 --- /dev/null +++ b/changelog/1.0.0.md @@ -0,0 +1,18 @@ +# 1.0.0 Release +This is the first `ServerAPI` **stable** release you can enjoy! + +Added features: +- installation wizard +- launching rust modules in parallel +- config support (you can change everything manually) +- implemented fancy html header (use of `maud` crate) +- implemented a text raw alternative to html in case client does not support it + + +Waited soon: +- crate organization, such as in my [`LimitPush`](https://github.com/heydocode/limitpush) project +- launching of processes via the CLI environment +- responsible CLI with commands +- inter-operability with [`LimitPush`](https://github.com/heydocode/limitpush) template, and any other bevy game +- feature organization +- custom multiplayer protocol that'll work with `LimitPush` if "mp-protocol" feature enabled \ No newline at end of file diff --git a/src/file_reader.rs b/src/file_reader.rs index 7e937d2..4141d2a 100644 --- a/src/file_reader.rs +++ b/src/file_reader.rs @@ -1,4 +1,4 @@ -use std::fs::{create_dir_all, File, metadata}; +use std::fs::{create_dir_all, metadata, File}; use std::io::{BufReader, Read}; use std::path::Path; @@ -41,7 +41,12 @@ pub fn mc_status_reader() -> String { } let contents = read_from_file(file_path.to_str().unwrap_or("config/logs.txt")); - if contents.clone().expect("Could not convert contents to Ok()").len() <= 5 { + if contents + .clone() + .expect("Could not convert contents to Ok()") + .len() + <= 5 + { String::from("The server's logs are empty! Is there a problem?") } else { contents.expect("Could not convert contents to Ok()") @@ -63,11 +68,14 @@ fn read_from_file(file_path: &str) -> Result { } // Attempt to open the file - let file = File::open(file_path).map_err(|e| format!("Error opening file '{}': {}", file_path, e))?; + let file = + File::open(file_path).map_err(|e| format!("Error opening file '{}': {}", file_path, e))?; let mut buf_reader = BufReader::new(file); let mut contents = String::new(); - - buf_reader.read_to_string(&mut contents).map_err(|e| format!("Error reading file '{}': {}", file_path, e))?; + + buf_reader + .read_to_string(&mut contents) + .map_err(|e| format!("Error reading file '{}': {}", file_path, e))?; Ok(contents) } diff --git a/src/file_writer.rs b/src/file_writer.rs index c648927..cffc064 100644 --- a/src/file_writer.rs +++ b/src/file_writer.rs @@ -1,6 +1,6 @@ +use async_std::fs::File; use async_std::fs::OpenOptions; use async_std::path::Path; -use async_std::fs::File; use async_std::prelude::*; pub async fn write_to_file(text: String, file_path: &str) -> Result<(), String> { @@ -11,27 +11,37 @@ pub async fn write_to_file(text: String, file_path: &str) -> Result<(), String> .await .map_err(|e| e.to_string())?; - file.write_all(text.as_bytes()).await.map_err(|e| e.to_string()) + file.write_all(text.as_bytes()) + .await + .map_err(|e| e.to_string()) } -pub async fn update_credentials(username: String, password: String, receiver: String) -> Result<(), String> { +pub async fn update_credentials( + username: String, + password: String, + receiver: String, +) -> Result<(), String> { let file_path = "config/smtp_account.txt"; let path = Path::new(file_path); let mut content = String::new(); { - let mut file = File::open(path) - .await - .map_err(|e| e.to_string())?; + let mut file = File::open(path).await.map_err(|e| e.to_string())?; file.read_to_string(&mut content) .await .map_err(|e| e.to_string())?; } let updated_content = content - .replace("username:example@gmail.com", &format!("username:{}", username)) + .replace( + "username:example@gmail.com", + &format!("username:{}", username), + ) .replace("password:password123123", &format!("password:{}", password)) - .replace("receiver:example@gmail.com", &format!("receiver:{}", receiver)); + .replace( + "receiver:example@gmail.com", + &format!("receiver:{}", receiver), + ); { let mut file = OpenOptions::new() diff --git a/src/mail.rs b/src/mail.rs index 3923bf4..15242d8 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -1,8 +1,11 @@ use crate::file_reader::smtp_account_reader; use crate::file_writer::write_to_file; use lettre::{ - message::{header::{self, ContentType}, MultiPart, SinglePart}, transport::smtp::authentication::Credentials, Message, - SmtpTransport, Transport, + message::{ + header::{self}, MaybeString, MultiPart, SinglePart + }, + transport::smtp::authentication::Credentials, + Message, SmtpTransport, Transport, }; use maud::PreEscaped; @@ -28,8 +31,7 @@ pub async fn mail_sender(title: &str, html: PreEscaped) { .singlepart( SinglePart::builder() .header(header::ContentType::TEXT_PLAIN) - .body(format!( - "Hello there!\nYour server is working fine! The next status email will be sent in 5 minutes.\n\nServer's Logs:\nYour client does not support html...")), + .body(MaybeString::String(String::from("Hello there!\nYour server is working fine! The next status email will be sent in 5 minutes.\n\nServer's Logs:\nYour client does not support html..."))), ) .singlepart( SinglePart::builder() @@ -50,7 +52,7 @@ pub async fn mail_sender(title: &str, html: PreEscaped) { match mailer.send(&email) { Ok(_) => { match write_to_file( - format!("Email has been sent successfully!"), + "Email has been sent successfully!".to_string(), "config/mail_logs.txt", ) .await diff --git a/src/main.rs b/src/main.rs index 3978d85..891ec68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,11 +12,8 @@ use scheduler::status_upload; use file_writer::write_to_file; use setup::check_config_components; use std::thread; -use tracing_subscriber; fn main() { - tracing_subscriber::fmt::init(); - let setup_handle = thread::Builder::new().name("setup".to_string()).spawn(|| { println!("Setup Process has been launched"); match check_config_components() { @@ -26,7 +23,7 @@ fn main() { async_std::task::block_on(async { match write_to_file( - format!("All config components are OK, loading the server.."), + "All config components are OK, loading the server..".to_string(), "config/logs.txt", ) .await @@ -37,23 +34,30 @@ fn main() { }); }); - if let Err(_) = setup_handle.expect("Unable to join setup handle").join() { + let mail_handle = thread::Builder::new() + .name("mail_server".to_string()) + .spawn(|| { + println!("Mail Server has been enabled"); + status_upload(); + println!("Mail Server has been disabled"); + }); + + if setup_handle + .expect("Unable to join setup handle") + .join() + .is_err() + { eprintln!("An error occured when tried to join setup handle"); - } else { - let mail_handle = thread::Builder::new() - .name("mail_server".to_string()) - .spawn(|| { - println!("Mail Server has been enabled"); - status_upload(); - println!("Mail Server has been disabled"); - }); - if let Err(_) = mail_handle.expect("Unable to join mail handle").join() { - eprintln!("An error occured when tried to join mail handle"); - } - // Please consider adding `else if` blocks until all handles won't be joined - else { - println!("All config components are OK, loading the server.."); - } + } else if mail_handle + .expect("Unable to join mail handle") + .join() + .is_err() + { + eprintln!("An error occured when tried to join mail handle"); + } + // Please consider adding `else if` blocks until all handles won't be joined + else { + println!("All config components are OK, loading the server.."); } /* MINECRAFT SERVER SUPPORT USING VALENCE diff --git a/src/setup.rs b/src/setup.rs index dffa194..fc6ac04 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,7 +1,7 @@ -use std::path::Path; use std::fs::OpenOptions; -use std::io::*; use std::io; +use std::io::*; +use std::path::Path; use crate::file_reader::smtp_account_reader; use crate::file_writer::update_credentials; @@ -9,7 +9,9 @@ use crate::file_writer::update_credentials; fn read_line() -> String { let mut input = String::new(); io::stdout().flush().unwrap(); - io::stdin().read_line(&mut input).expect("Failed to read line"); + io::stdin() + .read_line(&mut input) + .expect("Failed to read line"); input.trim().to_string() } @@ -18,7 +20,7 @@ pub fn check_config_components() -> std::result::Result<(), String> { Path::new("config/logs.txt"), Path::new("config/smtp_account.txt"), Path::new("config/mail_logs.txt"), - ]; + ]; for path in components.into_iter() { let prefix = path.parent().unwrap(); @@ -27,16 +29,12 @@ pub fn check_config_components() -> std::result::Result<(), String> { .read(true) .write(true) .create(true) + .truncate(false) .open(path) .map_err(|e| e.to_string())?; - if path == Path::new("config/smtp_account.txt") { - match smtp_account_reader() { - Err(_) => { - let _ = write!(file, "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n\n### The username is your gmail account (example@gmail.com)\n### The password is a 'password for apps' created in Google\n## NOTICE: To create an app-password, you have to have 2-step verification\n## enabled and maybe all rescue options of saving the account.").map_err(|e| e.to_string()); - setup_wizard(); - }, - _ => {} - } + if path == Path::new("config/smtp_account.txt") && smtp_account_reader().is_err() { + let _ = write!(file, "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n\n### The username is your gmail account (example@gmail.com)\n### The password is a 'password for apps' created in Google\n## NOTICE: To create an app-password, you have to have 2-step verification\n## enabled and maybe all rescue options of saving the account.").map_err(|e| e.to_string()); + setup_wizard(); } } Ok(()) @@ -52,70 +50,80 @@ pub fn setup_wizard() { match iter { 1 => { println!("Enter your smtp account username:"); - }, + } 2 => { println!("Can you confirm your smtp account username (Y or N)?"); - }, + } 3 => { println!("Enter your smtp account password:"); - }, + } 4 => { println!("Can you confirm your smtp account password (Y or N)?"); - }, + } 5 => { println!("Enter your gmail account as a receiver\n(you will receive status emails on this gmail address):") } 6 => { println!("Can you confirm your gmail account username (Y or N)?"); } - _ => () + _ => (), } let input = read_line(); match iter { 1 => { - println!("You have entered \"{}\" as your smtp account username", input); + println!( + "You have entered \"{}\" as your smtp account username", + input + ); smtp_account_username = input.clone(); iter += 1; - }, + } 2 => { if input.to_lowercase() == "y" { iter += 1; - } - else { + } else { iter = 1 } - }, + } 3 => { - println!("You have entered \"{}\" as your smtp account password", input); + println!( + "You have entered \"{}\" as your smtp account password", + input + ); smtp_account_password = input.clone(); iter += 1; - }, + } 4 => { if input.to_lowercase() == "y" { iter += 1; - } - else { + } else { iter = 3 } - }, + } 5 => { - println!("You have entered \"{}\" as your gmail account username", input); + println!( + "You have entered \"{}\" as your gmail account username", + input + ); receiver_gmail = input.clone(); iter += 1; } 6 => { if input.to_lowercase() == "y" { iter += 1; - } - else { + } else { iter = 5 } } _ => { async_std::task::block_on(async move { - update_credentials(smtp_account_username, smtp_account_password, receiver_gmail) - .await - .expect("Failed to update credentials"); + update_credentials( + smtp_account_username, + smtp_account_password, + receiver_gmail, + ) + .await + .expect("Failed to update credentials"); }); return; } diff --git a/src/tests.rs b/src/tests.rs index 0ac9b9f..900809f 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,86 +1,90 @@ #[cfg(test)] -mod tests { - use crate::*; - use async_std::fs::{self, File}; - use async_std::path::Path; - use async_std::prelude::*; - use file_writer::update_credentials; +use crate::*; +use async_std::fs::{self, File}; +use async_std::path::Path; +use async_std::prelude::*; +use file_writer::update_credentials; - #[test] - fn test_write_to_file() { - let test_file_path = "test_write_to_file.txt"; +#[test] +fn test_write_to_file() { + let test_file_path = "test_write_to_file.txt"; - // Use block_on to run the async code inside the test - async_std::task::block_on(async { - // Ensure the test file is clean - if Path::new(test_file_path).exists().await { - fs::remove_file(test_file_path) - .await - .expect("Failed to remove test file"); - } - - // Write to the file - write_to_file("Hello, world!".to_string(), test_file_path) + // Use block_on to run the async code inside the test + async_std::task::block_on(async { + // Ensure the test file is clean + if Path::new(test_file_path).exists().await { + fs::remove_file(test_file_path) .await - .expect("Failed to write to file"); + .expect("Failed to remove test file"); + } - // Read the file content - let mut file = File::open(test_file_path) - .await - .expect("Failed to open test file"); - let mut content = String::new(); - file.read_to_string(&mut content) - .await - .expect("Failed to read test file"); + // Write to the file + write_to_file("Hello, world!".to_string(), test_file_path) + .await + .expect("Failed to write to file"); - // Check the content - assert_eq!(content, "Hello, world!"); + // Read the file content + let mut file = File::open(test_file_path) + .await + .expect("Failed to open test file"); + let mut content = String::new(); + file.read_to_string(&mut content) + .await + .expect("Failed to read test file"); - // Clean up - fs::remove_file(test_file_path) - .await - .expect("Failed to remove test file"); - }); - } + // Check the content + assert_eq!(content, "Hello, world!"); + + // Clean up + fs::remove_file(test_file_path) + .await + .expect("Failed to remove test file"); + }); +} - #[test] - fn test_update_credentials() { - let test_file_path = "config/test_smtp_account.txt"; +#[test] +fn test_update_credentials() { + let test_file_path = "config/test_smtp_account.txt"; - // Use block_on to run the async code inside the test - async_std::task::block_on(async { - // Ensure the config directory exists - fs::create_dir_all("config") - .await - .expect("Failed to create config directory"); + // Use block_on to run the async code inside the test + async_std::task::block_on(async { + // Ensure the config directory exists + fs::create_dir_all("config") + .await + .expect("Failed to create config directory"); - // Prepare the test file - let initial_content = "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n"; - fs::write(test_file_path, initial_content) - .await - .expect("Failed to write initial content"); + // Prepare the test file + let initial_content = + "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n"; + fs::write(test_file_path, initial_content) + .await + .expect("Failed to write initial content"); - // Update credentials - update_credentials("new_username".to_string(), "new_password".to_string(), "examplereceiver".to_string()) - .await - .expect("Failed to update credentials"); - // Read the updated file content - let mut file = File::open(test_file_path) - .await - .expect("Failed to open test file"); - let mut content = String::new(); - file.read_to_string(&mut content) - .await - .expect("Failed to read test file"); + // Update credentials + update_credentials( + "new_username".to_string(), + "new_password".to_string(), + "examplereceiver".to_string(), + ) + .await + .expect("Failed to update credentials"); + // Read the updated file content + let mut file = File::open(test_file_path) + .await + .expect("Failed to open test file"); + let mut content = String::new(); + file.read_to_string(&mut content) + .await + .expect("Failed to read test file"); - // Check the updated content - let expected_content = "username:new_username\npassword:new_password\nreceiver:example_receiver\n"; - assert_eq!(content, expected_content); + // Check the updated content + let expected_content = + "username:new_username\npassword:new_password\nreceiver:example_receiver\n"; + assert_eq!(content, expected_content); - // Clean up - fs::remove_file(test_file_path) - .await - .expect("Failed to remove test file"); - }); - } + // Clean up + fs::remove_file(test_file_path) + .await + .expect("Failed to remove test file"); + }); } From 37fed7485fc639987cbac27ac5f14bcd2ea3f83b Mon Sep 17 00:00:00 2001 From: heydocode <169077757+heydocode@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:07:23 +0100 Subject: [PATCH 3/3] Update main.rs --- src/main.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main.rs b/src/main.rs index 891ec68..3e96094 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,30 +34,31 @@ fn main() { }); }); - let mail_handle = thread::Builder::new() - .name("mail_server".to_string()) - .spawn(|| { - println!("Mail Server has been enabled"); - status_upload(); - println!("Mail Server has been disabled"); - }); - if setup_handle .expect("Unable to join setup handle") .join() .is_err() { eprintln!("An error occured when tried to join setup handle"); - } else if mail_handle - .expect("Unable to join mail handle") - .join() - .is_err() - { - eprintln!("An error occured when tried to join mail handle"); } // Please consider adding `else if` blocks until all handles won't be joined else { - println!("All config components are OK, loading the server.."); + let mail_handle = thread::Builder::new() + .name("mail_server".to_string()) + .spawn(|| { + println!("Mail Server has been enabled"); + status_upload(); + println!("Mail Server has been disabled"); + }); + if mail_handle + .expect("Unable to join mail handle") + .join() + .is_err() + { + eprintln!("An error occured when tried to join mail handle"); + } else { + println!("All config components are OK, loading the server.."); + } } /* MINECRAFT SERVER SUPPORT USING VALENCE