diff --git a/Cargo.lock b/Cargo.lock index 2b4788d..8693eda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,1083 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "alsa-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0edcbbf9ef68f15ae1b620f722180b82a98b6f0628d30baa6b8d2a5abc87d58" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" - -[[package]] -name = "arc-swap" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" - -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - -[[package]] -name = "bindgen" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5" -dependencies = [ - "bitflags 1.2.1", - "cexpr", - "cfg-if", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "proc-macro2", - "quote 1.0.7", - "regex", - "rustc-hash", - "shlex", -] - -[[package]] -name = "bitflags" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "blake2b_simd" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "cc" -version = "1.0.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" - -[[package]] -name = "cexpr" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "chrono" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" -dependencies = [ - "num-integer", - "num-traits", - "time", -] - -[[package]] -name = "clang-sys" -version = "0.29.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.2.1", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "claxon" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688" - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.2.1", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - -[[package]] -name = "coreaudio-rs" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f229761965dad3e9b11081668a6ea00f1def7aa46062321b5ec245b834f6e491" -dependencies = [ - "bitflags 1.2.1", - "coreaudio-sys", -] - -[[package]] -name = "coreaudio-sys" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6570ee6e089131e928d5ec9236db9e818aa3cf850f48b0eec6ef700571271d4" -dependencies = [ - "bindgen", -] - -[[package]] -name = "cpal" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b55d55d69f403f62a95bd3c04b431e0aedf5120c70f15d07a8edd234443dd59" -dependencies = [ - "alsa-sys", - "core-foundation-sys", - "coreaudio-rs", - "lazy_static", - "libc", - "num-traits", - "stdweb", - "thiserror", - "winapi", -] - -[[package]] -name = "crossbeam" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" -dependencies = [ - "cfg-if", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ee0cc8804d5393478d743b035099520087a5186f3b93fa58cec08fa62407b6" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "lazy_static", - "maybe-uninit", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "crossterm" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7" -dependencies = [ - "bitflags 1.2.1", - "crossterm_winapi", - "lazy_static", - "libc", - "mio", - "parking_lot", - "signal-hook", - "winapi", -] - -[[package]] -name = "crossterm_winapi" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057b7146d02fb50175fd7dbe5158f6097f33d02831f43b4ee8ae4ddf67b68f5c" -dependencies = [ - "winapi", -] - -[[package]] -name = "dbus" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cd9e78c210146a1860f897db03412fd5091fd73100778e43ee255cca252cf32" -dependencies = [ - "libc", - "libdbus-sys", -] - -[[package]] -name = "directories" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "domasi" version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "crossbeam", - "crossterm", - "directories", - "notify-rust", - "rodio", - "serde", - "toml", -] - -[[package]] -name = "getrandom" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "hermit-abi" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" -dependencies = [ - "libc", -] - -[[package]] -name = "hound" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "lewton" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be42bea7971f4ba0ea1e215730c29bc1ff9bd2a9c10013912f42a8dcf8d77c0d" -dependencies = [ - "byteorder", - "ogg", - "tinyvec", -] - -[[package]] -name = "libc" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" - -[[package]] -name = "libdbus-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc12a3bc971424edbbf7edaf6e5740483444db63aa8e23d3751ff12a30f306f0" -dependencies = [ - "pkg-config", -] - -[[package]] -name = "libloading" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" -dependencies = [ - "cc", - "winapi", -] - -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "mac-notification-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb6b71a9a89cd38b395d994214297447e8e63b1ba5708a9a2b0b1048ceda76" -dependencies = [ - "cc", - "chrono", - "dirs", - "objc-foundation", -] - -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "memchr" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" - -[[package]] -name = "memoffset" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" -dependencies = [ - "autocfg", -] - -[[package]] -name = "minimp3" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce0cff6a0bfd3f8b6b2350819bbddd63bc65cc45e53888bdd0ff49dde16d2d5" -dependencies = [ - "minimp3-sys", - "slice-deque", -] - -[[package]] -name = "minimp3-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e21c73734c69dc95696c9ed8926a2b393171d98b3f5f5935686a26a487ab9b90" -dependencies = [ - "cc", -] - -[[package]] -name = "mio" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9971bc8349a361217a8f2a41f5d011274686bd4436465ba51730921039d7fb" -dependencies = [ - "lazy_static", - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" -dependencies = [ - "socket2", - "winapi", -] - -[[package]] -name = "nom" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "memchr", - "version_check", -] - -[[package]] -name = "notify-rust" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144acee6a0543dc74893e4b8a33936b5b0a94cc2d4ab024afd0c6daff7afc3c0" -dependencies = [ - "dbus", - "mac-notification-sys", - "winrt-notification", -] - -[[package]] -name = "ntapi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a31937dea023539c72ddae0e3571deadc1414b300483fa7aaec176168cfa9d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-integer" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" -dependencies = [ - "autocfg", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - -[[package]] -name = "ogg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79f1db9148be9d0e174bb3ac890f6030fcb1ed947267c5a91ee4c91b5a91e15" -dependencies = [ - "byteorder", -] - -[[package]] -name = "parking_lot" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" -dependencies = [ - "cfg-if", - "cloudabi", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pkg-config" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" - -[[package]] -name = "proc-macro2" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" -dependencies = [ - "unicode-xid 0.2.1", -] - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_users" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" -dependencies = [ - "getrandom", - "redox_syscall", - "rust-argon2", -] - -[[package]] -name = "regex" -version = "1.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" - -[[package]] -name = "rodio" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73bbf260262fd5501b7a17d6827e0d25c1127e921eb177150a060faf6e217a70" -dependencies = [ - "claxon", - "cpal", - "hound", - "lazy_static", - "lewton", - "minimp3", -] - -[[package]] -name = "rust-argon2" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" -dependencies = [ - "base64", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" -dependencies = [ - "proc-macro2", - "quote 1.0.7", - "syn 1.0.39", -] - -[[package]] -name = "shlex" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" - -[[package]] -name = "signal-hook" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed" -dependencies = [ - "libc", - "mio", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" -dependencies = [ - "arc-swap", - "libc", -] - -[[package]] -name = "slice-deque" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31ef6ee280cdefba6d2d0b4b78a84a1c1a3f3a4cec98c2d4231c8bc225de0f25" -dependencies = [ - "libc", - "mach", - "winapi", -] - -[[package]] -name = "smallvec" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" - -[[package]] -name = "socket2" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "winapi", -] - -[[package]] -name = "stdweb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "strum" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca6e4730f517e041e547ffe23d29daab8de6b73af4b6ae2a002108169f5e7da" - -[[package]] -name = "strum_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3384590878eb0cab3b128e844412e2d010821e7e091211b9d87324173ada7db8" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] - -[[package]] -name = "syn" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" -dependencies = [ - "proc-macro2", - "quote 1.0.7", - "unicode-xid 0.2.1", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid 0.0.4", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" -dependencies = [ - "proc-macro2", - "quote 1.0.7", - "syn 1.0.39", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tinyvec" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" - -[[package]] -name = "toml" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -dependencies = [ - "serde", -] - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[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 = "winrt" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30cba82e22b083dc5a422c2ee77e20dc7927271a0dc981360c57c1453cb48d" -dependencies = [ - "winapi", -] - -[[package]] -name = "winrt-notification" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c31a65da50d792c6f9bd2e3216249566c4fb1d2d34f9b7d2d66d2e93f62a242" -dependencies = [ - "strum", - "strum_macros", - "winapi", - "winrt", - "xml-rs", -] - -[[package]] -name = "xml-rs" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621" -dependencies = [ - "bitflags 0.9.1", -] diff --git a/Cargo.toml b/Cargo.toml index 55350c4..6ffc00d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,12 +7,3 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0" -clap = "2.33" -crossterm = "0.17" -directories = "3.0" -notify-rust = "4.0" -rodio = "0.11" -serde = { version = "1.0", features = ["derive"] } -toml = "0.5" -crossbeam = "0.7" diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index aa8b24c..0000000 --- a/src/config.rs +++ /dev/null @@ -1,73 +0,0 @@ -use anyhow::Result; -use directories::ProjectDirs; -use serde::{Deserialize, Serialize}; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::{Path, PathBuf}; -use std::time::Duration; - -const SETTINGS_FILE: &str = "settings.toml"; - -#[derive(Clone, Serialize, Deserialize, Debug)] -pub struct Config { - pub work_time: Duration, - pub short_break: Duration, - pub long_break: Duration, - pub sound_file: Option, -} - -impl Config { - pub fn new(work: u64, short_break: u64, long_break: u64) -> Self { - Config { - work_time: Duration::from_secs(work), - short_break: Duration::from_secs(short_break), - long_break: Duration::from_secs(long_break), - sound_file: None, - } - } - - pub fn save(config: &Config) -> Result<()> { - let config_directory = Self::get_config_directory(); - Self::write_to_file(&config_directory.join(SETTINGS_FILE), config) - } - - pub fn load() -> Option { - let config_file = Self::get_config_directory().join(SETTINGS_FILE); - Self::read_from_file(&config_file).ok() - } - - fn write_to_file>(path: &P, cfg: &Self) -> Result<()> { - let mut new_file = File::create(path.as_ref())?; - let serialized = toml::to_string(cfg)?; - - Ok(new_file.write_all(serialized.as_bytes())?) - } - - fn read_from_file>(path: &P) -> Result { - let mut toml_buf = vec![]; - let mut file = File::open(path.as_ref())?; - file.read_to_end(&mut toml_buf)?; - - Ok(toml::from_slice(&toml_buf)?) - } - - pub fn get_data_directory() -> PathBuf { - ProjectDirs::from("moe", "paoda", "domasi") - .unwrap() - .data_dir() - .to_path_buf() - } - - pub fn get_config_directory() -> PathBuf { - ProjectDirs::from("moe", "paoda", "domasi") - .unwrap() - .config_dir() - .to_path_buf() - } -} - -impl Default for Config { - fn default() -> Self { - Config::new(1500, 300, 600) - } -} diff --git a/src/lib.rs b/src/lib.rs index 25c1346..95b4e7e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ -pub use config::Config; pub use pomodoro::Pomodoro; -pub mod config; -pub mod pomodoro; +mod pomodoro; diff --git a/src/main.rs b/src/main.rs index 40b1922..9bd3182 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,204 +1,7 @@ -use clap::{App, Arg, ArgMatches, SubCommand}; -use crossbeam::channel::{unbounded, Receiver, Sender}; -use crossterm::{ - event::{poll, read, Event, KeyCode, KeyEvent, KeyModifiers}, - terminal::{disable_raw_mode, enable_raw_mode}, -}; -use domasi::pomodoro::{Alert, Remaining, Status}; -use domasi::{Config, Pomodoro}; -use std::fs; -use std::io::{self, Write}; -use std::path::{Path, PathBuf}; -use std::thread; +use domasi::Pomodoro; fn main() { - let matches = App::new("domasi") - .version("0.1.0") - .author("Rekai Musuka ") - .about("Yet another pomodoro timer.") - .arg( - Arg::with_name("create-config") - .short("C") - .long("create-config") - .help("Creates a Settings.toml and an alert directory"), - ) - .subcommand( - SubCommand::with_name("start") - .about("Start the Pomodoro Timer") - .arg( - Arg::with_name("alert") - .short("a") - .long("alert") - .value_name("FILE") - .takes_value(true) - .help("Aloud Sound. (Supports WAV, MP3, Vorbis, FLAC)"), - ), - ) - .get_matches(); + let mut timer: Pomodoro = Default::default(); - // match matches.subcommand() { - // ("start", Some(sub_matches)) => start(sub_matches), - // _ => {} - // } - - if matches.is_present("create-config") { - create_config() - } - - if let ("start", Some(sub_matches)) = matches.subcommand() { - start(sub_matches); - } -} - -pub fn create_config() { - let config_dir = Config::get_config_directory(); - let data_dir = Config::get_data_directory().join("alert"); - - if !config_dir.exists() { - fs::create_dir_all(&config_dir).unwrap_or_else(|err| { - panic!("Failed to create {}: {}", config_dir.to_string_lossy(), err) - }) - } - - if !data_dir.exists() { - fs::create_dir_all(&data_dir).unwrap_or_else(|err| { - panic!("Failed to create {}: {}", data_dir.to_string_lossy(), err) - }); - } - - let config: Config = Default::default(); - - Config::save(&config).unwrap_or_else(|err| { - let cfg_path = config_dir.to_string_lossy(); - panic!("Error while writing settings.toml to {}: {}", cfg_path, err); - }); - - let data_path = data_dir.to_string_lossy(); - let settings_path = config_dir.join("settings.toml"); - let settings_path = settings_path.to_string_lossy(); - - println!( - "Successfully created \"{}\" and \"{}\"", - settings_path, data_path - ); -} - -pub fn start(args: &ArgMatches) { - let mut pomodoro = Pomodoro::new(); - let (tx, rx): (Sender, Receiver) = unbounded(); - - // UI Thread - thread::spawn(move || loop { - if let Ok(status) = rx.recv() { - loop { - let (text, remain) = match Remaining::from_status(status) { - Some(seconds) => (seconds.to_string(), seconds.remaining_secs()), - None => ("??? Status: ??:??".to_string(), 0), - }; - - let out = io::stdout(); - let mut handle = out.lock(); - handle.write_all(text.as_bytes()).unwrap(); - handle.flush().unwrap(); - - // TODO: Make sure this isn't an issue. - if remain < 1 { - break; - } - - thread::sleep(Remaining::polling_interval()); - } - } - }); - - // User Input Thread - thread::spawn(|| setup_user_input().unwrap()); - - let config = { - match Config::load() { - Some(cfg) => cfg, - None => Default::default(), - } - }; - - let maybe_audio: Option; - - match args.value_of("alert") { - Some(path) => maybe_audio = Some(Path::new(path).to_path_buf()), - None => { - match &config.sound_file { - Some(path) => maybe_audio = Some(path.clone()), - None => { - // Look in the default locations - // check for .mp3, .wav, .ogg, .flac - let data_dir = Config::get_data_directory().join("alert"); - let data_dir_str = data_dir.to_string_lossy(); - - let items = fs::read_dir(&data_dir).unwrap_or_else(|_err| { - panic!("Unable to read the contents of {}", data_dir_str); - }); - - maybe_audio = get_audio_file(items); - } - } - } - } - - match maybe_audio { - Some(audio_path) => { - let default_device = rodio::default_output_device().unwrap(); - let alert = Alert::new(&audio_path, &default_device); - - pomodoro.start(config, tx, Some(&alert)); - } - None => pomodoro.start(config, tx, None), - } -} - -fn get_audio_file(items: std::fs::ReadDir) -> Option { - for maybe_entry in items { - if let Ok(entry) = maybe_entry { - if let Some(ext) = entry.path().extension() { - if let Some("mp3") | Some("wav") | Some("ogg") | Some("flac") = ext.to_str() { - return Some(entry.path()); - } - } - } - } - - None -} - -fn setup_user_input() -> crossterm::Result<()> { - enable_raw_mode()?; - get_user_input()?; - disable_raw_mode() -} - -fn get_user_input() -> crossterm::Result<()> { - loop { - if poll(Remaining::polling_interval())? { - if let Event::Key(event) = read()? { - handle_key_event(event); - } - } - } -} - -fn handle_key_event(event: KeyEvent) { - match event.code { - KeyCode::Char('c') => { - if let KeyModifiers::CONTROL = event.modifiers { - exit_domasi(0) - } - } - KeyCode::Esc | KeyCode::Char('q') => exit_domasi(0), - _ => {} - } -} - -fn exit_domasi(code: i32) { - disable_raw_mode().unwrap(); - - std::process::exit(code); + timer.start(); } diff --git a/src/pomodoro.rs b/src/pomodoro.rs index 50bd5ef..2e1f035 100644 --- a/src/pomodoro.rs +++ b/src/pomodoro.rs @@ -1,220 +1,166 @@ -use super::Config; -use crossbeam::channel::Sender; -use rodio::{Decoder, Device, Source}; use std::fmt::{Display, Formatter, Result as FmtResult}; -use std::fs::File; -use std::io::BufReader; -use std::path::Path; +use std::io::{self, Write}; +use std::thread; use std::time::{Duration, Instant}; -pub struct Alert<'a> { - path: &'a Path, - device: &'a Device, -} - -impl<'a> Alert<'a> { - pub fn new>(path: &'a P, device: &'a Device) -> Alert<'a> { - Alert { - path: path.as_ref(), - device, - } - } - - pub fn play(&self) { - if self.path.exists() { - let file = File::open(self.path).unwrap(); - let source = Decoder::new(BufReader::new(file)).unwrap(); - rodio::play_raw(&self.device, source.convert_samples()); - } - } - - pub fn load>(mut self, new_path: &'a P) -> Self { - self.path = new_path.as_ref(); - self - } -} - -#[derive(Copy, Clone, Debug)] -pub enum State { - Work, - ShortBreak, - LongBreak, - Inactive, -} - -impl std::fmt::Display for State { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match *self { - State::Work => f.write_str("Working: "), - State::ShortBreak => f.write_str("Resting: "), - State::LongBreak => f.write_str("REALLY Resting: "), - State::Inactive => f.write_str("Inactive: "), - } - } -} - -#[derive(Copy, Clone, Debug)] +#[derive(Debug, Copy, Clone, Default)] pub struct Pomodoro { - count: u64, state: State, + count: u64, + wait_start: Option, + paused: PausedState, } -impl Default for Pomodoro { - fn default() -> Self { - Pomodoro { - count: 0, - state: State::Inactive, - } - } -} - -impl<'a> Pomodoro { - pub fn start(&mut self, config: Config, tx: Sender, maybe_alert: Option<&Alert<'a>>) { - loop { - self.next(); - - if let Some(alert) = maybe_alert { - alert.play(); - } - - let _ = Self::notify(&self.state); - - match self.state { - State::Work => { - Self::send_to_clock(&tx, self.state, config.work_time); - Self::wait(config.work_time); - } - State::ShortBreak => { - Self::send_to_clock(&tx, self.state, config.short_break); - Self::wait(config.short_break); - } - State::LongBreak => { - Self::send_to_clock(&tx, self.state, config.long_break); - Self::wait(config.long_break); - } - State::Inactive => { - println!("Pomodoro Cycle is complete"); - break; - } - } - } - } -} +static POLLING_RATE: Duration = Duration::from_millis(300); +static WORK_TIME: u64 = 2; +static SBREAK_TIME: u64 = 2; +static LBREAK_TIME: u64 = 2; impl Pomodoro { - pub fn new() -> Pomodoro { - Pomodoro { - count: 0, - state: State::Inactive, - } + pub fn new() -> Self { + Self::default() } - fn next(&mut self) { - match self.state { - State::Work => { - self.count += 1; - - if (self.count % 4) == 0 { - self.state = State::LongBreak; - } else { - self.state = State::ShortBreak; - } + pub fn start(&mut self) { + loop { + if let Status::Complete = self.poll() { + break; } - State::LongBreak => self.state = State::Inactive, - State::ShortBreak => self.state = State::Work, - State::Inactive => self.state = State::Work, + thread::sleep(POLLING_RATE); } } - fn wait(duration: Duration) { - std::thread::sleep(duration); - } + fn poll(&mut self) -> Status { + let status = self.check(); - fn send_to_clock(tx: &Sender, state: State, length: Duration) { - let status = Status { - start: Instant::now(), - length, - state, + match status { + Status::Paused => { + assert!(self.paused.value); + let now = Instant::now(); + + self.paused.duration += match self.paused.previous { + Some(earlier) => now - earlier, + None => Default::default(), + }; + + self.paused.previous = Some(now); + } + Status::Active => self.display_time(), + Status::NextState => { + let (update_count, new_state) = self.next(); + + if let Count::Increase = update_count { + self.count += 1; + } + + self.state = new_state; + self.wait_start = match new_state { + State::Inactive => None, + State::Work | State::ShortBreak | State::LongBreak => Some(Instant::now()), + }; + + self.display_time(); + } + Status::Complete => { + println!("\rPomodoro Cycle Complete!"); + } + Status::Inactive => {} }; - tx.send(status).unwrap(); + status } - fn notify(state: &State) -> Result<(), anyhow::Error> { - let mut toast = notify_rust::Notification::new(); - match state { - State::Work => toast - .summary("Time to Work!") - .body("Remember to stay focused!") - .show()?, - State::ShortBreak | State::LongBreak => toast - .summary("Break Time!") - .body("Enjoy your well deserved rest!") - .show()?, - State::Inactive => toast - .summary("Pomodoro Cycle Complete.") - .body("Now waiting for user input....") - .show()?, - }; + fn display_time(&self) { + if let Some(earlier) = self.wait_start { + let wait = Instant::now() - earlier; + let left: Clock = (Self::wait_times(self.state) - wait).into(); + let _ = Self::print(&format!("\r{} {}", self.state, left)); + } + } + fn print(text: &str) -> io::Result<()> { + let out = io::stdout(); + let mut handle = out.lock(); + handle.write_all(text.as_bytes())?; + handle.flush()?; Ok(()) } -} -#[derive(Copy, Clone, Debug)] -pub struct Status { - pub start: Instant, - pub length: Duration, - pub state: State, -} + fn next(&self) -> (Count, State) { + match self.state { + State::Work => { + let state: State = if (self.count + 1) % 4 == 0 { + State::LongBreak + } else { + State::ShortBreak + }; -pub struct Remaining { - state: State, - remaining: u64, - seconds: u64, - hours: u64, - minutes: u64, -} - -impl Remaining { - pub fn from_status(status: Status) -> Option { - let now = Instant::now(); - let maybe_elapsed = now.checked_duration_since(status.start); - - match maybe_elapsed { - Some(duration) => { - let remaining = status.length.as_secs() - duration.as_secs(); - - let hours = remaining / 3600; - let minutes = (remaining - (hours * 3600)) / 60; - let seconds = remaining - (hours * 3600) - (minutes * 60); - - Some(Self { - state: status.state, - remaining, - hours, - minutes, - seconds, - }) + (Count::Increase, state) } - None => None, + State::ShortBreak | State::Inactive => (Count::Remain, State::Work), + State::LongBreak => (Count::Remain, State::Inactive), } } - pub fn remaining_secs(&self) -> u64 { - self.remaining + fn check(&self) -> Status { + if self.paused.value { + return Status::Paused; + } + + match self.wait_start { + Some(earlier) => { + let diff: Duration = (Instant::now() - self.paused.duration) - earlier; + + if diff > Self::wait_times(self.state) { + Status::NextState + } else { + Status::Active + } + } + None => { + if self.count == 0 { + Status::NextState + } else { + Status::Complete + } + } + } } - pub fn polling_interval() -> Duration { - Duration::from_millis(500) + fn wait_times(state: State) -> Duration { + match state { + State::Work => Duration::from_secs(WORK_TIME), + State::ShortBreak => Duration::from_secs(SBREAK_TIME), + State::LongBreak => Duration::from_secs(LBREAK_TIME), + _ => unreachable!("Can not have Pomodoro state = State::Inactive and wait_start = Some(...) at the same time.") + } } } -impl Display for Remaining { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - f.write_str("\r")?; - write!(f, "{}", self.state)?; +struct Clock { + hours: u64, + minutes: u64, + seconds: u64, +} +impl From for Clock { + fn from(dur: Duration) -> Self { + let dur = dur.as_secs(); + + let hours = dur / 3600; + let minutes = (dur - (hours * 3600)) / 60; + let seconds = dur - (hours * 3600) - (minutes * 60); + + Self { + hours, + minutes, + seconds, + } + } +} + +impl Display for Clock { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { if self.hours > 0 { // No need to print the hours if there are none. if self.hours < 10 { @@ -237,3 +183,50 @@ impl Display for Remaining { } } } + +#[derive(Debug, Copy, Clone, Default)] +struct PausedState { + value: bool, + duration: Duration, + previous: Option, +} + +#[derive(Debug, Copy, Clone)] +enum Count { + Increase, + Remain, +} + +#[derive(Debug, Copy, Clone)] +enum Status { + Paused, + Active, + NextState, + Inactive, + Complete, +} + +#[derive(Debug, Copy, Clone)] +enum State { + Inactive, + Work, + ShortBreak, + LongBreak, +} + +impl Default for State { + fn default() -> Self { + State::Inactive + } +} + +impl Display for State { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match *self { + State::Work => f.write_str("Working: "), + State::ShortBreak => f.write_str("Resting: "), + State::LongBreak => f.write_str("REALLY Resting: "), + State::Inactive => f.write_str("Inactive: "), + } + } +}