diff --git a/Cargo.lock b/Cargo.lock index 80b3fb9..bfe861f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -73,12 +88,39 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -103,6 +145,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" + [[package]] name = "cassowary" version = "0.3.0" @@ -196,6 +244,16 @@ dependencies = [ "unicode-width 0.2.0", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -264,6 +322,26 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -280,6 +358,92 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[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", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -303,6 +467,31 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.15.2" @@ -315,6 +504,118 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.61" @@ -338,6 +639,145 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "2.7.1" @@ -348,6 +788,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -398,6 +844,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -420,6 +872,21 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "0.8.11" @@ -444,6 +911,23 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -453,12 +937,65 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +[[package]] +name = "openssl" +version = "0.10.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +dependencies = [ + "bitflags 2.8.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -488,6 +1025,30 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -566,6 +1127,71 @@ dependencies = [ "thiserror", ] +[[package]] +name = "reqwest" +version = "0.12.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + +[[package]] +name = "ring" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustix" version = "0.38.44" @@ -579,6 +1205,45 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rustls" +version = "0.23.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.19" @@ -591,12 +1256,44 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.8.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.217" @@ -638,6 +1335,18 @@ dependencies = [ "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 = "shlex" version = "1.3.0" @@ -675,18 +1384,49 @@ dependencies = [ "libc", ] +[[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" +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.98" @@ -698,6 +1438,61 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.8.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" +dependencies = [ + "cfg-if", + "fastrand", + "getrandom 0.3.1", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" version = "2.0.11" @@ -718,6 +1513,64 @@ dependencies = [ "syn", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio 1.0.3", + "pin-project-lite", + "socket2", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "0.8.20" @@ -752,6 +1605,58 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "tui" version = "0.19.0" @@ -777,6 +1682,7 @@ dependencies = [ "dirs", "lazy_static", "rand", + "reqwest", "serde", "serde_json", "toml", @@ -807,12 +1713,56 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[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" @@ -854,6 +1804,19 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.100" @@ -886,6 +1849,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -917,6 +1890,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1083,6 +2086,42 @@ dependencies = [ "bitflags 2.8.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -1123,3 +2162,52 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index bd1b397..1dde530 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ lazy_static = "1.5.0" anyhow = "1.0.95" chrono = { version = "0.4", features = ["serde"] } comfy-table = "7.1.4" +reqwest = { version = "0.12.12", features = ["blocking"] } diff --git a/README.md b/README.md index 94017c6..ec09b06 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,14 @@ word and asks you to type it as fast as possible. The game tracks your typing sp different game modes, such as uppercase and punctuation, to help you improve your typing skills in different areas. ## Installation -To install Typy on Linux, you can use the following command: +To install Typy, you can use the [Cargo] package manager: + +[Cargo]: https://doc.rust-lang.org/cargo/ ```bash -curl -sSL https://raw.githubusercontent.com/Pazl27/typy-cli/master/scripts/install.sh | bash +cargo install --git "https://github.com/Pazl27/typy-cli.git" --tag "v0.8.0" ``` -This command downloads and runs the installation script from the Typy GitHub repository. The script will handle the installation process for you, ensuring that Typy is set up correctly on your system. - If you prefer to get the newest version and compile it yourself, follow these steps: 1. Clone the Typy repository: @@ -144,5 +144,5 @@ If you want to provide a new language to the Typy repository, feel free to creat ## Uninstall ```bash -curl -sSL https://raw.githubusercontent.com/Pazl27/typy-cli/master/scripts/uninstall.sh | bash +cargo uninstall typy-cli ``` diff --git a/scripts/install.sh b/scripts/install.sh deleted file mode 100755 index 3c0cbef..0000000 --- a/scripts/install.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# Define paths -BIN_NAME="typy" -LOCAL_DIR="$HOME/.local/share" -CONFIG_PATH="$LOCAL_DIR/$BIN_NAME/english.txt" -INSTALL_DIR="$HOME/your-repo" -GIT_TAG="v0.8.0" - -# Function to move binary with appropriate privileges -move_binary() { - if command -v sudo &> /dev/null; then - sudo mv /tmp/$BIN_NAME /usr/bin/$BIN_NAME - sudo chmod +x /usr/bin/$BIN_NAME - elif command -v doas &> /dev/null; then - doas mv /tmp/$BIN_NAME /usr/bin/$BIN_NAME - doas chmod +x /usr/bin/$BIN_NAME - elif [ "$(id -u)" -eq 0 ]; then - mv /tmp/$BIN_NAME /usr/bin/$BIN_NAME - chmod +x /usr/bin/$BIN_NAME - else - echo "Please run this script with elevated privileges (sudo, doas, or as root)." - exit 1 - fi -} - -# Create directories if they don't exist -mkdir -p "$LOCAL_DIR/$BIN_NAME" - -# Download the binary and move it to the correct location -echo "Downloading and installing $BIN_NAME..." -curl -L https://github.com/Pazl27/typy-cli/releases/download/$GIT_TAG/$BIN_NAME -o /tmp/$BIN_NAME - -# Move the binary to /usr/bin and make it executable -move_binary - -# Move any required files to the ~/.local folder (e.g., configuration files) -echo "Setting up configuration files..." -curl -L https://github.com/Pazl27/typy-cli/releases/download/$GIT_TAG/english.txt -o "$CONFIG_PATH" - -echo "Installation complete! You can now run the CLI tool by typing '$BIN_NAME' in your terminal." diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh deleted file mode 100755 index f8189b3..0000000 --- a/scripts/uninstall.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# Define paths -BIN_NAME="typy" -LOCAL_DIR="$HOME/.local/share" -BIN_PATH="/usr/bin/$BIN_NAME" -CONFIG_PATH="$LOCAL_DIR/$BIN_NAME/english.txt" -CONFIG_DIR="$LOCAL_DIR/$BIN_NAME" - -# Function to remove the binary with appropriate privileges -remove_binary() { - if command -v sudo &> /dev/null; then - sudo rm -f "$BIN_PATH" - elif command -v doas &> /dev/null; then - doas rm -f "$BIN_PATH" - elif [ "$(id -u)" -eq 0 ]; then - rm -f "$BIN_PATH" - else - echo "Please run this script with elevated privileges (sudo, doas, or as root)." - exit 1 - fi -} - -# Remove the binary -echo "Removing $BIN_NAME binary..." -remove_binary - -# Remove configuration files -echo "Removing configuration files..." -rm -f "$CONFIG_PATH" -rm -rf "$CONFIG_DIR" - -echo "Cleanup complete! $BIN_NAME has been removed from your system." diff --git a/src/config/config_tables/cursor_style.rs b/src/config/config_tables/cursor_style.rs index 9978041..825fd44 100644 --- a/src/config/config_tables/cursor_style.rs +++ b/src/config/config_tables/cursor_style.rs @@ -4,15 +4,19 @@ use crate::config::toml_parser::get_config; use crate::config::toml_parser::CursorTable; pub struct CursorKind { - pub style: SetCursorStyle + pub style: SetCursorStyle, } impl CursorKind { pub fn new() -> Self { - - let cursor_table: CursorTable = get_config().lock().unwrap().get_cursor().unwrap_or(CursorTable { - style: Some("DefaultUserShape".to_owned()) - }); + let cursor_table: CursorTable = + get_config() + .lock() + .unwrap() + .get_cursor() + .unwrap_or(CursorTable { + style: Some("DefaultUserShape".to_owned()), + }); let cursor_kind = match cursor_table.style.as_deref() { Some("DefaultUserShape") => SetCursorStyle::DefaultUserShape, @@ -25,17 +29,14 @@ impl CursorKind { _ => SetCursorStyle::DefaultUserShape, }; - CursorKind { - style: cursor_kind, - } + CursorKind { style: cursor_kind } } } impl Default for CursorKind { fn default() -> Self { CursorKind { - style: SetCursorStyle::DefaultUserShape + style: SetCursorStyle::DefaultUserShape, } } } - diff --git a/src/config/config_tables/graph_colors.rs b/src/config/config_tables/graph_colors.rs index 4cc0957..4c7f4d7 100644 --- a/src/config/config_tables/graph_colors.rs +++ b/src/config/config_tables/graph_colors.rs @@ -10,7 +10,6 @@ pub struct Graph { impl Graph { pub fn new() -> Self { - let theme_colors: Graph = match get_config().lock().unwrap().get_graph() { Some(colors) => { let data = colors diff --git a/src/config/config_tables/mode_settings.rs b/src/config/config_tables/mode_settings.rs index adc2661..620b715 100644 --- a/src/config/config_tables/mode_settings.rs +++ b/src/config/config_tables/mode_settings.rs @@ -16,7 +16,8 @@ impl ModeSettings { let default_modes = settings .default_mode .map(|m| { - let modes: Vec = m.split(',') + let modes: Vec = m + .split(',') .filter_map(|mode| ModeType::from_str(mode.trim()).ok()) .collect(); if modes.contains(&ModeType::Normal) { @@ -37,7 +38,11 @@ impl ModeSettings { .map(|c| c.clamp(0.0, 1.0)) .unwrap_or(0.2); - ModeSettings { default_modes, uppercase_chance, punctuation_chance } + ModeSettings { + default_modes, + uppercase_chance, + punctuation_chance, + } } None => ModeSettings::default(), }; diff --git a/src/config/config_tables/theme.rs b/src/config/config_tables/theme.rs index c90a152..10ee285 100644 --- a/src/config/config_tables/theme.rs +++ b/src/config/config_tables/theme.rs @@ -12,7 +12,6 @@ pub struct ThemeColors { impl ThemeColors { pub fn new() -> Self { - let theme_colors: ThemeColors = match get_config().lock().unwrap().get_theme() { Some(colors) => { let fg = colors @@ -67,20 +66,49 @@ fn hex_to_rgb(hex: &str) -> Option { } } - #[cfg(test)] mod theme_tests { use super::*; #[test] fn test_hex_to_rgb() { - assert_eq!(hex_to_rgb("#ffffff"), Some(Color::Rgb { r: 255, g: 255, b: 255 })); + assert_eq!( + hex_to_rgb("#ffffff"), + Some(Color::Rgb { + r: 255, + g: 255, + b: 255 + }) + ); assert_eq!(hex_to_rgb("#000000"), Some(Color::Rgb { r: 0, g: 0, b: 0 })); - assert_eq!(hex_to_rgb("#ff0000"), Some(Color::Rgb { r: 255, g: 0, b: 0 })); - assert_eq!(hex_to_rgb("#00ff00"), Some(Color::Rgb { r: 0, g: 255, b: 0 })); - assert_eq!(hex_to_rgb("#0000ff"), Some(Color::Rgb { r: 0, g: 0, b: 255 })); - assert_eq!(hex_to_rgb("#123456"), Some(Color::Rgb { r: 18, g: 52, b: 86 })); - assert_eq!(hex_to_rgb("#abcdef"), Some(Color::Rgb { r: 171, g: 205, b: 239 })); + assert_eq!( + hex_to_rgb("#ff0000"), + Some(Color::Rgb { r: 255, g: 0, b: 0 }) + ); + assert_eq!( + hex_to_rgb("#00ff00"), + Some(Color::Rgb { r: 0, g: 255, b: 0 }) + ); + assert_eq!( + hex_to_rgb("#0000ff"), + Some(Color::Rgb { r: 0, g: 0, b: 255 }) + ); + assert_eq!( + hex_to_rgb("#123456"), + Some(Color::Rgb { + r: 18, + g: 52, + b: 86 + }) + ); + assert_eq!( + hex_to_rgb("#abcdef"), + Some(Color::Rgb { + r: 171, + g: 205, + b: 239 + }) + ); assert_eq!(hex_to_rgb("#12345"), None); assert_eq!(hex_to_rgb("#1234567"), None); assert_eq!(hex_to_rgb("123456"), None); diff --git a/src/config/toml_parser.rs b/src/config/toml_parser.rs index 4194482..715bedd 100644 --- a/src/config/toml_parser.rs +++ b/src/config/toml_parser.rs @@ -1,13 +1,12 @@ -use std::fs; -use toml; -use serde::{Deserialize, Serialize}; use dirs::home_dir; -use std::path::PathBuf; use lazy_static::lazy_static; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; use std::sync::Mutex; +use toml; -#[derive(Serialize, Deserialize)] -#[derive(Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct ThemeTable { pub fg: Option, pub missing: Option, @@ -15,35 +14,31 @@ pub struct ThemeTable { pub accent: Option, } -#[derive(Serialize, Deserialize)] -#[derive(Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct GraphTable { pub data: Option, pub title: Option, pub axis: Option, } -#[derive(Serialize, Deserialize)] -#[derive(Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct CursorTable { pub style: Option, } -#[derive(Serialize, Deserialize)] -#[derive(Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct ModesTable { pub default_mode: Option, pub uppercase_chance: Option, pub punctuation_chance: Option, } -#[derive(Serialize, Deserialize)] -#[derive(Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct LanguageTable { - pub lang: Option + pub lang: Option, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Default)] pub struct ConfigToml { theme: Option, graph: Option, @@ -96,18 +91,6 @@ impl ConfigToml { } } -impl Default for ConfigToml { - fn default() -> Self { - ConfigToml { - theme: None, - graph: None, - cursor: None, - modes: None, - language: None, - } - } -} - // Declare the static instance of ConfigToml using lazy_static lazy_static! { static ref CONFIG: Mutex = Mutex::new(ConfigToml::new()); @@ -117,4 +100,3 @@ lazy_static! { pub fn get_config() -> &'static Mutex { &CONFIG } - diff --git a/src/mode/mode_selector.rs b/src/mode/mode_selector.rs index 48d5bf8..5b496a7 100644 --- a/src/mode/mode_selector.rs +++ b/src/mode/mode_selector.rs @@ -57,7 +57,11 @@ impl Mode { modes.push(ModeType::Normal); }); - Ok(Mode { modes, duration: 0, settings }) + Ok(Mode { + modes, + duration: 0, + settings, + }) } pub fn add_duration(mut self, duration: u64) -> Self { @@ -65,9 +69,9 @@ impl Mode { self } - pub fn transform(&self, list: &mut Vec>) { + pub fn transform(&self, list: &mut [Vec]) { let mut rng = rand::rng(); - let punctuations = vec![".", ",", "!", "?", ";", ":", "-"]; + let punctuations = [".", ",", "!", "?", ";", ":", "-"]; for mode in &self.modes { match mode { @@ -90,11 +94,11 @@ impl Mode { for sublist in list.iter_mut() { let len = sublist.len(); if len > 1 { - for i in 0..len - 1 { + for item in sublist.iter_mut().take(len - 1) { if rng.random_bool(self.settings.punctuation_chance.into()) { let punctuation = punctuations[rng.random_range(0..punctuations.len())]; - sublist[i].push_str(punctuation); + item.push_str(punctuation); } } } @@ -155,4 +159,3 @@ mod mode_tests { assert_eq!(list[0].len(), 2); } } - diff --git a/src/scores/finish_overview.rs b/src/scores/finish_overview.rs index 3a08286..ec2e86b 100644 --- a/src/scores/finish_overview.rs +++ b/src/scores/finish_overview.rs @@ -1,45 +1,52 @@ use crate::scores::graph; +use anyhow::{Context, Result}; use crossterm::cursor::MoveTo; use crossterm::event::{read, Event, KeyEvent}; use crossterm::style::SetForegroundColor; use crossterm::terminal::{Clear, ClearType}; use crossterm::ExecutableCommand; -use anyhow::{Result, Context}; -use crate::terminal; -use crate::scores::Stats; use crate::config::theme::ThemeColors; +use crate::scores::Stats; +use crate::terminal; -pub fn show_stats( - mut stdout: &std::io::Stdout, - stats: Stats, - theme: &ThemeColors -) -> Result<()> { - - stdout.execute(Clear(ClearType::All)).context("Failed to clear terminal")?; +pub fn show_stats(mut stdout: &std::io::Stdout, stats: Stats, theme: &ThemeColors) -> Result<()> { + stdout + .execute(Clear(ClearType::All)) + .context("Failed to clear terminal")?; // Draw infos - stdout.execute(MoveTo(15, 16)).context("Failed to move cursor")?; + stdout + .execute(MoveTo(15, 16)) + .context("Failed to move cursor")?; stdout .execute(SetForegroundColor(theme.missing)) .context("Failed to set foreground color")?; print!("WPM"); - stdout.execute(MoveTo(15, 17)).context("Failed to move cursor")?; + stdout + .execute(MoveTo(15, 17)) + .context("Failed to move cursor")?; stdout .execute(SetForegroundColor(theme.accent)) .context("Failed to set foreground color")?; print!("{:02}", stats.wpm() as i32); - stdout.execute(MoveTo(15, 20)).context("Failed to move cursor")?; + stdout + .execute(MoveTo(15, 20)) + .context("Failed to move cursor")?; stdout .execute(SetForegroundColor(theme.missing)) .context("Failed to set foreground color")?; print!("RAW"); - stdout.execute(MoveTo(15, 21)).context("Failed to move cursor")?; + stdout + .execute(MoveTo(15, 21)) + .context("Failed to move cursor")?; stdout .execute(SetForegroundColor(theme.accent)) .context("Failed to set foreground color")?; print!("{:02}", stats.raw_wpm() as i32); - stdout.execute(MoveTo(37, 25)).context("Failed to move cursor")?; + stdout + .execute(MoveTo(37, 25)) + .context("Failed to move cursor")?; stdout .execute(SetForegroundColor(theme.accent)) .context("Failed to set foreground color")?; diff --git a/src/scores/mod.rs b/src/scores/mod.rs index 2878059..7709753 100644 --- a/src/scores/mod.rs +++ b/src/scores/mod.rs @@ -1,6 +1,6 @@ pub mod finish_overview; -mod stats; -pub mod progress; mod graph; +pub mod progress; +mod stats; pub use stats::Stats; diff --git a/src/scores/progress/data.rs b/src/scores/progress/data.rs index 72c8c31..623cf64 100644 --- a/src/scores/progress/data.rs +++ b/src/scores/progress/data.rs @@ -151,7 +151,7 @@ impl Score { self.timestamp.format("%H:%M:%S").to_string() } - pub fn sort_scores(scores: &mut Vec) { + pub fn sort_scores(scores: &mut [Score]) { scores.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)); } @@ -174,7 +174,7 @@ impl Score { impl Averages { fn new(score: Score) -> Result { - Ok(Self::calculate_averages(score)?) + Self::calculate_averages(score) } fn calculate_averages(score: Score) -> Result { let averages = Data::get_averages()?; @@ -186,9 +186,9 @@ impl Averages { let mut raw_count = averages.raw_avg.count; let mut accuracy_count = averages.accuracy_avg.count; - wpm_sum += score.wpm as u32; - raw_sum += score.raw as u32; - accuracy_sum += score.accuracy as f32; + wpm_sum += score.wpm; + raw_sum += score.raw; + accuracy_sum += score.accuracy; wpm_count += 1; raw_count += 1; diff --git a/src/scores/progress/mod.rs b/src/scores/progress/mod.rs index 89f1010..35ca48b 100644 --- a/src/scores/progress/mod.rs +++ b/src/scores/progress/mod.rs @@ -1,4 +1,4 @@ -pub mod display; mod data; +pub mod display; pub use data::*; diff --git a/src/terminal/game.rs b/src/terminal/game.rs index 30a6261..14ce238 100644 --- a/src/terminal/game.rs +++ b/src/terminal/game.rs @@ -67,9 +67,9 @@ pub fn run(mode: Mode, theme: ThemeColors) -> Result<()> { let mut stdout = stdout(); let language = language::Language::new(); - let file_name = format!(".local/share/typy/{}.txt", language.lang); - let mut game = - Game::new(word_provider::get_words(&file_name).context("Failed to get words from file")?); + let mut game = Game::new( + word_provider::get_words(&language.lang).context("Failed to get words from file")?, + ); mode.transform(&mut game.list); @@ -82,7 +82,7 @@ pub fn run(mode: Mode, theme: ThemeColors) -> Result<()> { for (i, words) in game.list.iter().enumerate() { print_words(x, y + i as u16, words, &stdout, &theme)?; stdout - .execute(MoveTo(x, y as u16)) + .execute(MoveTo(x, y)) .context("Failed to move cursor")?; } @@ -150,7 +150,7 @@ pub fn run(mode: Mode, theme: ThemeColors) -> Result<()> { game.quit = true; break; } - match handle_input(&mut game, &mut stdout, code, &mut stats, &theme, x, y)? { + match handle_input(&mut game, &stdout, code, &mut stats, &theme, x, y)? { InputAction::Continue => continue, InputAction::Break => break, InputAction::None => {} @@ -203,7 +203,7 @@ fn reset_terminal(mut stdout: &std::io::Stdout) -> Result<()> { fn print_words( x: u16, y: u16, - words: &Vec, + words: &[String], mut stdout: &std::io::Stdout, theme: &ThemeColors, ) -> Result<()> { diff --git a/src/terminal/keyboard.rs b/src/terminal/keyboard.rs index 51ec907..a1cf78b 100644 --- a/src/terminal/keyboard.rs +++ b/src/terminal/keyboard.rs @@ -245,7 +245,7 @@ fn add_incorrect_char( let position_x = game.player.position_x; let words = game.get_word_string(game.player.position_y); - if words.len() >= MAX_WORD_LENGTH as usize { + if words.len() >= MAX_WORD_LENGTH { return Ok(InputAction::Continue); } diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index 6218c76..43199c3 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -1,6 +1,6 @@ -mod keyboard; mod game; +mod keyboard; mod terminal_utils; -pub use game::{Game, run}; +pub use game::{run, Game}; pub use terminal_utils::{calc_middle_for_text, close_typy}; diff --git a/src/word_provider/finder.rs b/src/word_provider/finder.rs index 192dd0e..34d76fd 100644 --- a/src/word_provider/finder.rs +++ b/src/word_provider/finder.rs @@ -1,26 +1,48 @@ -use anyhow::Result; +use anyhow::{bail, Context, Result}; use dirs::home_dir; +use reqwest::blocking::get; use std::{ - fs::File, + fs::{create_dir_all, write, File}, io::{BufRead, BufReader}, path::PathBuf, + sync::LazyLock, }; use rand::seq::IndexedRandom; -pub fn find(lenght: i32, res: &str) -> Result, std::io::Error> { - let path = if res.contains("resources") { - PathBuf::from(res) +static WORDS_DIR: LazyLock> = LazyLock::new(|| { + if cfg!(test) { + Some(PathBuf::from("./resources/")) } else { - let mut home_path = home_dir().ok_or(std::io::Error::new( - std::io::ErrorKind::NotFound, - "Home directory not found", - ))?; - home_path.push(res); - home_path + home_dir().map(|p| p.join(".local/share/typy")) + } +}); +const WORDS_URL: &str = + "https://raw.githubusercontent.com/Pazl27/typy-cli/refs/heads/master/resources/"; + +pub fn find(language: &str, lenght: i32) -> Result> { + let Some(words_file) = WORDS_DIR + .as_ref() + .map(|p| p.join(format!("{language}.txt"))) + else { + bail!("Unable to find home directory"); }; - let words = read_file(path.to_str().unwrap())?; + // Download words file if not already present + if !words_file.exists() { + create_dir_all(words_file.parent().unwrap())?; + let language_url = format!("{WORDS_URL}{language}.txt"); + let resp = get(&language_url) + .context("Failed to download words file from ".to_owned() + &language_url)?; + write( + &words_file, + resp.text() + .context("Failed to extract text from words file download")?, + ) + .with_context(|| format!("Failed to save words file to {words_file:#?}"))?; + } + + let words = read_file(words_file.to_str().unwrap())?; let mut word = random_word(&words); let mut fitted_words = Vec::new(); @@ -42,13 +64,13 @@ fn read_file(path: &str) -> Result, std::io::Error> { Ok(words) } -fn random_word(words: &Vec) -> String { +fn random_word(words: &[String]) -> String { let mut rng = rand::rng(); let word = words.choose(&mut rng).unwrap(); word.to_string() } -fn check_if_fits(word: &String, fitted_words: &mut Vec, lenght: i32) -> bool { +fn check_if_fits(word: &str, fitted_words: &mut [String], lenght: i32) -> bool { let list_length: i32 = fitted_words .iter() .map(|s| s.chars().count() as i32) @@ -84,8 +106,8 @@ mod finder_tests { let word = "Hello".to_string(); let mut fitted_words = Vec::new(); let lenght = 5; - assert_eq!(check_if_fits(&word, &mut fitted_words, lenght), true); + assert!(check_if_fits(&word, &mut fitted_words, lenght)); fitted_words.push("Hello".to_string()); - assert_eq!(check_if_fits(&word, &mut fitted_words, lenght), false); + assert!(!check_if_fits(&word, &mut fitted_words, lenght)); } } diff --git a/src/word_provider/mod.rs b/src/word_provider/mod.rs index 1c3fe63..1d05b32 100644 --- a/src/word_provider/mod.rs +++ b/src/word_provider/mod.rs @@ -1,26 +1,25 @@ mod finder; -use finder::find; use anyhow::Result; +use finder::find; const LENGTH: i32 = 70; -pub fn get_words(res: &str) -> Result>> { +pub fn get_words(language: &str) -> Result>> { let mut words = Vec::new(); for _ in 0..3 { - words.push(find(LENGTH, res)?); + words.push(find(language, LENGTH)?); } Ok(words) } #[cfg(test)] - mod word_provider_tests { use super::*; #[test] fn test_get_words() { - let words = get_words("resources/english.txt"); + let words = get_words("english"); for word in &words.unwrap() { let mut length = 0;