diff options
| -rw-r--r-- | Cargo.lock | 684 | ||||
| -rw-r--r-- | Cargo.toml | 12 | ||||
| -rw-r--r-- | flake.lock | 12 | ||||
| -rw-r--r-- | flake.nix | 2 | ||||
| -rw-r--r-- | src/gui/message.rs | 15 | ||||
| -rw-r--r-- | src/gui/mod.rs | 43 | ||||
| -rw-r--r-- | src/gui/question.rs | 69 | ||||
| -rw-r--r-- | src/main.rs | 30 | ||||
| -rw-r--r-- | src/util/event.rs | 73 | ||||
| -rw-r--r-- | src/util/mod.rs | 1 | 
10 files changed, 622 insertions, 319 deletions
| @@ -14,36 +14,25 @@ dependencies = [  ]  [[package]] -name = "ansi_term" -version = "0.12.1" +name = "android_system_properties" +version = "0.1.5"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"  dependencies = [ - "winapi", + "libc",  ]  [[package]]  name = "anyhow" -version = "1.0.45" +version = "1.0.68"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"  [[package]]  name = "autocfg" -version = "1.0.1" +version = "1.1.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"  [[package]]  name = "bitflags" @@ -52,12 +41,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"  [[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]]  name = "cassowary"  version = "0.3.0"  source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"  [[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + +[[package]]  name = "cfg-if"  version = "1.0.0"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -65,30 +66,160 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"  [[package]]  name = "chrono" -version = "0.4.19" +version = "0.4.23"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"  dependencies = [ - "libc", + "iana-time-zone", + "js-sys",   "num-integer",   "num-traits",   "time", + "wasm-bindgen",   "winapi",  ]  [[package]]  name = "clap" -version = "2.34.0" +version = "4.1.4"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"  dependencies = [ - "ansi_term", - "atty",   "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell",   "strsim", - "textwrap", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor",   "unicode-width", - "vec_map", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi", +] + +[[package]] +name = "cxx" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc",  ]  [[package]] @@ -109,110 +240,187 @@ version = "0.1.0"  dependencies = [   "anyhow",   "chrono", + "clap", + "crossterm",   "rusqlite",   "rusqlite_migration",   "serde",   "serde_json", - "structopt", - "termion",   "tui",  ]  [[package]]  name = "getrandom" -version = "0.2.3" +version = "0.2.8"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"  dependencies = [   "cfg-if",   "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1",  ]  [[package]]  name = "hashbrown" -version = "0.11.2" +version = "0.12.3"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"  dependencies = [   "ahash",  ]  [[package]]  name = "hashlink" -version = "0.7.0" +version = "0.8.1"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"  dependencies = [   "hashbrown",  ]  [[package]]  name = "heck" -version = "0.3.3" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.2.6"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"  dependencies = [ - "unicode-segmentation", + "libc",  ]  [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "iana-time-zone" +version = "0.1.53"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"  dependencies = [   "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys",  ]  [[package]]  name = "itoa" -version = "0.4.8" +version = "1.0.5"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"  [[package]] -name = "lazy_static" -version = "1.4.0" +name = "js-sys" +version = "0.3.60"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +]  [[package]]  name = "libc" -version = "0.2.105" +version = "0.2.139"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"  [[package]]  name = "libsqlite3-sys" -version = "0.23.1" +version = "0.25.2"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd5850c449b40bacb498b2bbdfaff648b1b055630073ba8db499caf2d0ea9f2" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa"  dependencies = [   "pkg-config",   "vcpkg",  ]  [[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]]  name = "log" -version = "0.4.14" +version = "0.4.17"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"  dependencies = [   "cfg-if",  ]  [[package]] -name = "memchr" -version = "2.4.1" +name = "mio" +version = "0.8.5"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +]  [[package]]  name = "num-integer" -version = "0.1.44" +version = "0.1.45"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"  dependencies = [   "autocfg",   "num-traits", @@ -220,30 +428,53 @@ dependencies = [  [[package]]  name = "num-traits" -version = "0.2.14" +version = "0.2.15"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"  dependencies = [   "autocfg",  ]  [[package]] -name = "numtoa" -version = "0.1.0" +name = "once_cell" +version = "1.17.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"  [[package]] -name = "once_cell" -version = "1.8.0" +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "parking_lot" +version = "0.12.1"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +]  [[package]]  name = "pkg-config" -version = "0.3.22" +version = "0.3.26"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"  [[package]]  name = "proc-macro-error" @@ -271,45 +502,36 @@ dependencies = [  [[package]]  name = "proc-macro2" -version = "1.0.32" +version = "1.0.50"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"  dependencies = [ - "unicode-xid", + "unicode-ident",  ]  [[package]]  name = "quote" -version = "1.0.10" +version = "1.0.23"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"  dependencies = [   "proc-macro2",  ]  [[package]]  name = "redox_syscall" -version = "0.2.10" +version = "0.2.16"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"  dependencies = [   "bitflags",  ]  [[package]] -name = "redox_termios" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" -dependencies = [ - "redox_syscall", -] - -[[package]]  name = "rusqlite" -version = "0.26.1" +version = "0.28.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a82b0b91fad72160c56bf8da7a549b25d7c31109f52cc1437eac4c0ad2550a7" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a"  dependencies = [   "bitflags",   "chrono", @@ -317,40 +539,65 @@ dependencies = [   "fallible-streaming-iterator",   "hashlink",   "libsqlite3-sys", - "memchr",   "smallvec",  ]  [[package]]  name = "rusqlite_migration" -version = "0.5.0" +version = "1.0.1"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2abaa6d2e015b59342d088590b0c0051ba1ed5508780f8c31315b2986ebbf5b6" +checksum = "e2a7ba8908f9b41e2b240a3de0790517c7a636df1f7bb7612276a2d0a42f9ce2"  dependencies = [   "log",   "rusqlite",  ]  [[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]]  name = "ryu" -version = "1.0.5" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[package]] +name = "scopeguard" +version = "1.1.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"  [[package]]  name = "serde" -version = "1.0.130" +version = "1.0.152"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"  dependencies = [   "serde_derive",  ]  [[package]]  name = "serde_derive" -version = "1.0.130" +version = "1.0.152"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"  dependencies = [   "proc-macro2",   "quote", @@ -359,9 +606,9 @@ dependencies = [  [[package]]  name = "serde_json" -version = "1.0.70" +version = "1.0.91"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"  dependencies = [   "itoa",   "ryu", @@ -369,113 +616,108 @@ dependencies = [  ]  [[package]] -name = "smallvec" -version = "1.7.0" +name = "signal-hook" +version = "0.3.14"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +]  [[package]] -name = "strsim" -version = "0.8.0" +name = "signal-hook-mio" +version = "0.2.3"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +]  [[package]] -name = "structopt" -version = "0.3.26" +name = "signal-hook-registry" +version = "1.4.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"  dependencies = [ - "clap", - "lazy_static", - "structopt-derive", + "libc",  ]  [[package]] -name = "structopt-derive" -version = "0.4.18" +name = "smallvec" +version = "1.10.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"  [[package]] -name = "syn" -version = "1.0.81" +name = "strsim" +version = "0.10.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"  [[package]] -name = "termion" -version = "1.5.6" +name = "syn" +version = "1.0.107"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"  dependencies = [ - "libc", - "numtoa", - "redox_syscall", - "redox_termios", + "proc-macro2", + "quote", + "unicode-ident",  ]  [[package]] -name = "textwrap" -version = "0.11.0" +name = "termcolor" +version = "1.2.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"  dependencies = [ - "unicode-width", + "winapi-util",  ]  [[package]]  name = "time" -version = "0.1.43" +version = "0.1.45"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"  dependencies = [   "libc", + "wasi 0.10.0+wasi-snapshot-preview1",   "winapi",  ]  [[package]]  name = "tui" -version = "0.16.0" +version = "0.19.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c8ce4e27049eed97cfa363a5048b09d995e209994634a0efc26a14ab6c0c23" +checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1"  dependencies = [   "bitflags",   "cassowary", - "termion", + "crossterm",   "unicode-segmentation",   "unicode-width",  ]  [[package]] -name = "unicode-segmentation" -version = "1.8.0" +name = "unicode-ident" +version = "1.0.6"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"  [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-segmentation" +version = "1.10.0"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"  [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-width" +version = "0.1.10"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"  [[package]]  name = "vcpkg" @@ -484,22 +726,76 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"  [[package]] -name = "vec_map" -version = "0.8.2" +name = "version_check" +version = "0.9.4"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"  [[package]] -name = "version_check" -version = "0.9.3" +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"  [[package]]  name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1"  source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"  [[package]]  name = "winapi" @@ -518,7 +814,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"  [[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]]  name = "winapi-x86_64-pc-windows-gnu"  version = "0.4.0"  source = "registry+https://github.com/rust-lang/crates.io-index"  checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" @@ -2,15 +2,15 @@  name = "flashcards"  version = "0.1.0"  authors = ["Joris GUYONVARCH"] -edition = "2018" +edition = "2021"  [dependencies]  anyhow = "1.0"  chrono = "0.4" -rusqlite = { version = "0.26", features = [ "chrono" ] } -rusqlite_migration = "0.5" +clap = { version = "4.1", features = ["derive"] } +crossterm = "0.25" +rusqlite = { version = "0.28", features = [ "chrono" ] } +rusqlite_migration = "1.0"  serde = { version = "1.0", features = ["derive"] }  serde_json = "1.0" -structopt = "0.3" -termion = "1.5" -tui = "0.16" +tui = "0.19" @@ -17,11 +17,11 @@      },      "nixpkgs": {        "locked": { -        "lastModified": 1669040464, -        "narHash": "sha256-A+9mPkCdd6ei8EfbRX8butcneRuXbwiGpoyeh9TbAwg=", +        "lastModified": 1674714815, +        "narHash": "sha256-9b7xFXdCoabk1yq1IBDtW7HcxguHH7m/PTUKf9u9b/8=",          "owner": "nixos",          "repo": "nixpkgs", -        "rev": "328d723f89af95a280d3046e6124786b03b0e2bf", +        "rev": "8a0e5429e55ba745615a90509b3a8548d73e68fa",          "type": "github"        },        "original": { @@ -47,11 +47,11 @@          ]        },        "locked": { -        "lastModified": 1668998422, -        "narHash": "sha256-G/BklIplCHZEeDIabaaxqgITdIXtMolRGlwxn9jG2/Q=", +        "lastModified": 1674699969, +        "narHash": "sha256-gkhhGV7zBVoEIl1sFSz67r0d8fTeY57coY/+zDzxrbk=",          "owner": "oxalica",          "repo": "rust-overlay", -        "rev": "68ab029c93f8f8eed4cf3ce9a89a9fd4504b2d6e", +        "rev": "480f9cc37db841d1fd3ac0b0c059d48e5eb6946c",          "type": "github"        },        "original": { @@ -19,7 +19,7 @@        {          devShell = mkShell {            buildInputs = [ -            rust-bin.stable."1.60.0".default +            rust-bin.stable."1.64.0".default              watchexec              cargo-watch              sqlite diff --git a/src/gui/message.rs b/src/gui/message.rs index 29b5d8a..0136f1c 100644 --- a/src/gui/message.rs +++ b/src/gui/message.rs @@ -1,7 +1,6 @@  use crate::gui::util; -use crate::util::event::{Event, Events}; +use crossterm::event::{self, Event, KeyCode, KeyModifiers};  use anyhow::Result; -use termion::event::Key;  use tui::{      backend::Backend,      layout::{Alignment, Constraint, Direction, Layout}, @@ -11,7 +10,6 @@ use tui::{  pub fn show<B: Backend>(      terminal: &mut Terminal<B>, -    events: &Events,      title: &str,      message: &str,      wait: bool, @@ -33,14 +31,13 @@ pub fn show<B: Backend>(          })?;          if wait { -            if let Event::Input(key) = events.next()? { -                match key { -                    Key::Char('q') | Key::Ctrl('c') => { -                        break; -                    } -                    _ => {} +            // if crossterm::event::poll(Duration::from_secs(0))? { +            if let Event::Key(key) = event::read()? { +                if key.code == KeyCode::Char('q') || key.code == KeyCode::Char('c') && key.modifiers.contains(KeyModifiers::CONTROL) { +                    break;                  }              } +            // }          } else {              break;          } diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 358e4b5..1053de1 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -2,31 +2,44 @@ pub mod message;  pub mod question;  pub mod util; -use crate::{db, space_repetition, util::event::Events, util::time}; +use crate::{db, space_repetition, util::time};  use anyhow::Result;  use rusqlite::Connection; -use std::io; -use termion::{raw::IntoRawMode, raw::RawTerminal, screen::AlternateScreen}; -use tui::{backend::TermionBackend, Terminal}; +use std::io::Stdout; +use tui::{backend::CrosstermBackend, Terminal}; +use crossterm::{terminal}; -pub type Term = Terminal<TermionBackend<AlternateScreen<RawTerminal<io::Stdout>>>>; +pub type Term = Terminal<CrosstermBackend<Stdout>>; -pub fn terminal() -> Result<Term> { -    let stdout = io::stdout().into_raw_mode()?; -    let stdout = AlternateScreen::from(stdout); -    let backend = TermionBackend::new(stdout); +pub fn setup_terminal() -> Result<Term> { +    terminal::enable_raw_mode()?; +    let mut stdout = std::io::stdout(); +    crossterm::execute!(stdout, terminal::EnterAlternateScreen)?; +    let backend = CrosstermBackend::new(stdout);      Ok(Terminal::new(backend)?)  } -pub fn start(conn: &Connection, term: &mut Term, events: &Events, deck_name: &str) -> Result<()> { +pub fn restore_terminal(term: &mut Term) -> Result<()> { +    terminal::disable_raw_mode()?; +    crossterm::execute!(term.backend_mut(), terminal::LeaveAlternateScreen)?; +    term.show_cursor()?; +    Ok(()) +} + +pub fn start( +    conn: &Connection, +    term: &mut Term, +    deck_name: &str, +    hide_progress: bool, +) -> Result<()> {      let mut answers = 0;      loop {          let now = time::seconds_since_unix_epoch()?; -        let title = title(deck_name, answers, db::count_available(conn).unwrap_or(0)); +        let title = title(deck_name, answers, db::count_available(conn).unwrap_or(0), hide_progress);          match db::pick_random_ready(conn) { -            Some(card) => match question::ask(term, events, &title, &card)? { +            Some(card) => match question::ask(term, &title, &card)? {                  question::Response::Aborted => break,                  question::Response::Answered { difficulty } => {                      answers += 1; @@ -45,7 +58,7 @@ pub fn start(conn: &Connection, term: &mut Term, events: &Events, deck_name: &st                      }                      None => "Aucune carte n’est disponible. Votre deck est-il vide ?".to_string(),                  }; -                let _ = message::show(term, events, &title, &message, true); +                let _ = message::show(term, &title, &message, true);                  break;              }          } @@ -54,8 +67,8 @@ pub fn start(conn: &Connection, term: &mut Term, events: &Events, deck_name: &st      Ok(())  } -fn title(deck_name: &str, answers: i32, available_cards: i32) -> String { -    if answers == 0 && available_cards == 0 { +fn title(deck_name: &str, answers: i32, available_cards: i32, hide_progress: bool) -> String { +    if answers == 0 && available_cards == 0 || hide_progress {          deck_name.to_string()      } else if available_cards == 0 {          let from = answers; diff --git a/src/gui/question.rs b/src/gui/question.rs index 2aa6e65..73e4a93 100644 --- a/src/gui/question.rs +++ b/src/gui/question.rs @@ -1,11 +1,10 @@  use crate::{      gui::util,      model::{difficulty, difficulty::Difficulty, Card}, -    util::event::{Event, Events},      util::serialization,  };  use anyhow::Result; -use termion::event::Key; +use crossterm::event::{self, Event, KeyCode, KeyModifiers};  use tui::{      backend::Backend,      layout::{Alignment, Constraint, Direction, Layout}, @@ -32,7 +31,6 @@ pub enum Response {  pub fn ask<B: Backend>(      terminal: &mut Terminal<B>, -    events: &Events,      title: &str,      card: &Card,  ) -> Result<Response> { @@ -136,10 +134,10 @@ pub fn ask<B: Backend>(              }          })?; -        if let Event::Input(key) = events.next()? { +        if let Event::Key(key) = event::read()? {              match state.answer { -                Answer::Write => match key { -                    Key::Char('\n') => { +                Answer::Write => match key.code { +                    KeyCode::Char('\n') => {                          let difficulty = if is_correct(&state.input, &card.responses) {                              Difficulty::Good                          } else { @@ -147,57 +145,58 @@ pub fn ask<B: Backend>(                          };                          state.answer = Answer::Difficulty { difficulty }                      } -                    Key::Char(c) => { -                        state.input.push(c); -                        if is_correct(&state.input, &card.responses) { -                            state.answer = Answer::Difficulty { -                                difficulty: Difficulty::Good, +                    KeyCode::Char(c) => { +                        if key.modifiers.contains(KeyModifiers::CONTROL) { +                            if c == 'u' { +                                state.input.clear(); +                            } else if c == 'w' { +                                let mut words = state.input.split_whitespace().collect::<Vec<&str>>(); +                                if !words.is_empty() { +                                    words.truncate(words.len() - 1); +                                    let joined_words = words.join(" "); +                                    let space = if !words.is_empty() { " " } else { "" }; +                                    state.input = format!("{joined_words}{space}"); +                                } +                            } else if c == 'c' { +                                return Ok(Response::Aborted); +                            } +                        } else { +                            state.input.push(c); +                            if is_correct(&state.input, &card.responses) { +                                state.answer = Answer::Difficulty { +                                    difficulty: Difficulty::Good, +                                }                              }                          }                      } -                    Key::Backspace => { +                    KeyCode::Backspace => {                          state.input.pop();                      } -                    Key::Ctrl('u') => { -                        state.input.clear(); -                    } -                    Key::Ctrl('w') => { -                        let mut words = state.input.split_whitespace().collect::<Vec<&str>>(); -                        if !words.is_empty() { -                            words.truncate(words.len() - 1); -                            state.input = format!( -                                "{}{}", -                                words.join(" "), -                                if !words.is_empty() { " " } else { "" } -                            ); -                        } -                    } -                    Key::Ctrl('c') => { -                        return Ok(Response::Aborted); -                    }                      _ => {}                  },                  Answer::Difficulty {                      difficulty: selected, -                } => match key { -                    Key::Left => { +                } => match key.code { +                    KeyCode::Left => {                          for d in relative_element(&card.state.difficulties(), &selected, -1).iter()                          {                              state.answer = Answer::Difficulty { difficulty: *d }                          }                      } -                    Key::Right => { +                    KeyCode::Right => {                          for d in relative_element(&card.state.difficulties(), &selected, 1).iter() {                              state.answer = Answer::Difficulty { difficulty: *d }                          }                      } -                    Key::Char('\n') => { +                    KeyCode::Enter => {                          return Ok(Response::Answered {                              difficulty: selected,                          })                      } -                    Key::Ctrl('c') => { -                        return Ok(Response::Aborted); +                    KeyCode::Char('c') => { +                        if key.modifiers.contains(KeyModifiers::CONTROL) { +                            return Ok(Response::Aborted); +                        }                      }                      _ => {}                  }, diff --git a/src/main.rs b/src/main.rs index a791f29..c671d0e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,35 +6,41 @@ mod space_repetition;  mod sync;  mod util; -use crate::util::event::Events;  use anyhow::Result; +use clap::Parser;  use std::path::PathBuf; -use structopt::StructOpt; -#[derive(StructOpt)] -#[structopt()] +#[derive(Parser)] +#[clap()]  struct Opt { -    #[structopt(long, default_value = "deck.deck")] +    /// Path to the deck +    #[clap(long, default_value = "deck.deck")]      deck: String, + +    /// Hide current and remaining card counts +    #[clap(long)] +    hide_progress: bool,  }  fn main() -> Result<()> { -    let deck_path = Opt::from_args().deck; +    let args = Opt::parse(); +    let deck_path = args.deck;      let mut conn = db::init(db_path(&deck_path))?;      let deck_name = deck::pp_from_path(&deck_path).unwrap_or_else(|| "Deck".to_string());      sync::run(&mut conn, &deck_path)?; -    let mut term = gui::terminal()?; -    let events = Events::new(); -    match gui::start(&conn, &mut term, &events, &deck_name) { -        Ok(()) => Ok(()), +    let mut term = gui::setup_terminal()?; + +    match gui::start(&conn, &mut term, &deck_name, args.hide_progress) { +        Ok(()) => (),          Err(msg) => {              // Show errors in TUI, otherwise they are hidden -            gui::message::show(&mut term, &events, &deck_name, &format!("{msg}"), true)?; -            Err(msg) +            gui::message::show(&mut term, &deck_name, &format!("{msg}"), true)?          }      } + +    gui::restore_terminal(&mut term)  }  fn db_path(deck_path: &str) -> String { diff --git a/src/util/event.rs b/src/util/event.rs deleted file mode 100644 index 379df99..0000000 --- a/src/util/event.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::io; -use std::sync::mpsc; -use std::thread; -use std::time::Duration; - -use termion::event::Key; -use termion::input::TermRead; - -pub enum Event<I> { -    Input(I), -    Tick, -} - -/// A small event handler that wrap termion input and tick events. Each event -/// type is handled in its own thread and returned to a common `Receiver` -pub struct Events { -    rx: mpsc::Receiver<Event<Key>>, -    input_handle: thread::JoinHandle<()>, -    tick_handle: thread::JoinHandle<()>, -} - -#[derive(Debug, Clone, Copy)] -pub struct Config { -    pub tick_rate: Duration, -} - -impl Default for Config { -    fn default() -> Config { -        Config { -            tick_rate: Duration::from_millis(250), -        } -    } -} - -impl Events { -    pub fn new() -> Events { -        Events::with_config(Config::default()) -    } - -    pub fn with_config(config: Config) -> Events { -        let (tx, rx) = mpsc::channel(); -        let input_handle = { -            let tx = tx.clone(); -            thread::spawn(move || { -                let stdin = io::stdin(); -                for key in stdin.keys().flatten() { -                    if let Err(err) = tx.send(Event::Input(key)) { -                        eprintln!("{err}"); -                        return; -                    } -                } -            }) -        }; -        let tick_handle = { -            thread::spawn(move || loop { -                if let Err(err) = tx.send(Event::Tick) { -                    eprintln!("{err}"); -                    break; -                } -                thread::sleep(config.tick_rate); -            }) -        }; -        Events { -            rx, -            input_handle, -            tick_handle, -        } -    } - -    pub fn next(&self) -> Result<Event<Key>, mpsc::RecvError> { -        self.rx.recv() -    } -} diff --git a/src/util/mod.rs b/src/util/mod.rs index c866e61..3444389 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,4 +1,3 @@  #[allow(dead_code)] -pub mod event;  pub mod serialization;  pub mod time; | 
