init commit containing existing app

This commit is contained in:
Triston Armstrong 2024-05-05 09:19:16 -05:00
commit b8964ab0bc
No known key found for this signature in database
GPG Key ID: FADE6AC6F956FC52
14 changed files with 1362 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

773
Cargo.lock generated Normal file
View File

@ -0,0 +1,773 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "allocator-api2"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "backtrace"
version = "0.3.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "cassowary"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "castaway"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
dependencies = [
"rustversion",
]
[[package]]
name = "cc"
version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "color-eyre"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "compact_str"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f"
dependencies = [
"castaway",
"cfg-if",
"itoa",
"ryu",
"static_assertions",
]
[[package]]
name = "crossterm"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
dependencies = [
"bitflags",
"crossterm_winapi",
"libc",
"mio",
"parking_lot",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]]
name = "either"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
[[package]]
name = "eyre"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "gimli"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indoc"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.154"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "lru"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
dependencies = [
"hashbrown",
]
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "miniz_oxide"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
]
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys",
]
[[package]]
name = "object"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "parking_lot"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.52.5",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "proc-macro2"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ratatui"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a564a852040e82671dc50a37d88f3aa83bbc690dfc6844cfe7a2591620206a80"
dependencies = [
"bitflags",
"cassowary",
"compact_str",
"crossterm",
"indoc",
"itertools",
"lru",
"paste",
"stability",
"strum",
"unicode-segmentation",
"unicode-width",
]
[[package]]
name = "redox_syscall"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
dependencies = [
"bitflags",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustversion"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47"
[[package]]
name = "rusty_standup"
version = "0.1.0"
dependencies = [
"color-eyre",
"crossterm",
"ratatui",
]
[[package]]
name = "ryu"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "signal-hook"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"libc",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "stability"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strum"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "syn"
version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"sharded-slab",
"thread_local",
"tracing-core",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-width"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[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 = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm 0.52.5",
"windows_aarch64_msvc 0.52.5",
"windows_i686_gnu 0.52.5",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.5",
"windows_x86_64_gnu 0.52.5",
"windows_x86_64_gnullvm 0.52.5",
"windows_x86_64_msvc 0.52.5",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

11
Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "rusty_standup"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
color-eyre = "0.6.3"
crossterm = "0.27.0"
ratatui = "0.26.2"

254
src/app.rs Normal file
View File

@ -0,0 +1,254 @@
use crate::{tui, ui};
use color_eyre::eyre::{Context, Ok};
use color_eyre::Result;
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
use ratatui::widgets::ListState;
use ratatui::Frame;
pub struct StatefulList {
pub state: ListState,
pub items: Vec<String>,
}
#[derive(PartialEq)]
pub enum Pane {
Todo,
Completed,
}
pub struct App {
pub exit: bool,
pub adding_new: bool,
pub new_value: String,
pub todos: StatefulList,
pub completed: StatefulList,
pub pane_in_focus: Pane,
}
impl App {
pub fn new() -> App {
App {
exit: false,
adding_new: false,
new_value: String::new(),
pane_in_focus: Pane::Todo,
todos: StatefulList {
state: ListState::default(),
items: vec![],
},
completed: StatefulList {
state: ListState::default(),
items: vec![],
},
}
}
pub fn run(&mut self, terminal: &mut tui::Tui) -> Result<()> {
while !self.exit {
terminal.draw(|frame| self.render_frame(frame))?;
self.handle_events().wrap_err("handle events failed")?;
}
Ok(())
}
fn render_frame(&mut self, frame: &mut Frame) {
ui::Ui::default().build(frame, self);
}
fn handle_events(&mut self) -> Result<()> {
// check for timeout event
if !event::poll(std::time::Duration::from_millis(16))? {
return Ok(());
}
match event::read()? {
// check if event key is pressed
Event::Key(key_event) => {
// guard clause preventing
if key_event.kind != KeyEventKind::Press {
return Ok(());
}
return self
.handle_key_event(key_event)
.wrap_err_with(|| format!("handling key event failed:\n{key_event:#?}"));
}
_ => Ok(()),
}
}
fn add_new_todo(&mut self) {
self.adding_new = true;
}
fn handle_enter_press(&mut self) {
match self.pane_in_focus {
Pane::Todo => self.complete_todo(),
Pane::Completed => self.revert_todo(),
}
}
fn prev_pane(&mut self) {
match self.pane_in_focus {
Pane::Todo => self.pane_in_focus = Pane::Completed,
Pane::Completed => self.pane_in_focus = Pane::Todo,
}
}
fn next_pane(&mut self) {
match self.pane_in_focus {
Pane::Todo => self.pane_in_focus = Pane::Completed,
Pane::Completed => self.pane_in_focus = Pane::Todo,
}
}
fn handle_edit_mode_key_events(&mut self, key_code: KeyCode) -> Result<()> {
match key_code {
KeyCode::Char(value) => {
self.new_value.push(value);
Ok(())
}
KeyCode::Backspace => {
self.new_value.pop();
Ok(())
}
KeyCode::Esc => {
self.new_value = String::new();
self.adding_new = false;
Ok(())
}
KeyCode::Enter => {
self.todos.items.push(self.new_value.clone());
self.todos.state.select(Some(self.todos.items.len() - 1));
self.adding_new = false;
self.new_value = String::new();
Ok(())
}
_ => Ok(()),
}
}
fn handle_normal_mode_key_events(&mut self, key_code: KeyCode) -> Result<()> {
match key_code {
KeyCode::Char('q') => self.exit(),
KeyCode::Char('a') => self.add_new_todo(),
KeyCode::Char('j') => self.go_next(),
KeyCode::Char('k') => self.go_prev(),
KeyCode::Char('h') => self.prev_pane(),
KeyCode::Char('l') => self.next_pane(),
KeyCode::Char('d') => self.delete(),
KeyCode::Enter => self.handle_enter_press(),
_ => {}
};
Ok(())
}
fn handle_key_event(&mut self, key_event: KeyEvent) -> Result<()> {
match self.adding_new {
true => self.handle_edit_mode_key_events(key_event.code),
false => self.handle_normal_mode_key_events(key_event.code),
}
}
fn exit(&mut self) {
self.exit = true;
}
fn go_next(&mut self) {
match self.pane_in_focus {
Pane::Todo => {
match self.todos.items.len() {
i if i > 0 => self.todos.next(),
_ => {}
};
}
Pane::Completed => {
match self.completed.items.len() {
i if i > 0 => self.completed.next(),
_ => {}
};
}
};
}
fn go_prev(&mut self) {
match self.pane_in_focus {
Pane::Todo => {
match self.todos.items.len() {
i if i > 0 => self.todos.previous(),
_ => {}
};
}
Pane::Completed => {
match self.completed.items.len() {
i if i > 0 => self.completed.previous(),
_ => {}
};
}
}
}
fn complete_todo(&mut self) {
if self.todos.items.len() < 1 {
return;
}
let curr = self.todos.state.selected().unwrap();
let item_at_curr = self.todos.items.get(curr).unwrap();
self.completed.items.push(item_at_curr.to_string());
self.todos.items.remove(curr);
}
fn revert_todo(&mut self) {
if self.completed.items.len() < 1 {
return;
}
let curr = self.completed.state.selected().unwrap();
let item_at_curr = self.completed.items.get(curr).unwrap();
self.todos.items.push(item_at_curr.to_string());
self.completed.items.remove(curr);
}
fn delete(&mut self) {
self.go_prev();
match self.pane_in_focus {
Pane::Todo => {
let curr = self.todos.state.selected().unwrap();
self.todos.items.remove(curr);
}
Pane::Completed => {
let curr = self.completed.state.selected().unwrap();
self.completed.items.remove(curr);
}
}
}
}
impl StatefulList {
fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}
fn previous(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(i));
}
}

25
src/errors.rs Normal file
View File

@ -0,0 +1,25 @@
use std::panic;
use crate::tui;
use color_eyre::{config::HookBuilder, eyre};
use color_eyre::{eyre::Ok, Result};
pub fn install_hooks() -> Result<()> {
let (panic_hook, eyre_hook) = HookBuilder::default().into_hooks();
let panic_hook = panic_hook.into_panic_hook();
panic::set_hook(Box::new(move |panic_info| {
tui::restore().unwrap();
panic_hook(panic_info);
}));
let eyre_hook = eyre_hook.into_eyre_hook();
eyre::set_hook(Box::new(
move |error: &(dyn std::error::Error + 'static)| {
tui::restore().unwrap();
eyre_hook(error)
},
))?;
Ok(())
}

17
src/main.rs Normal file
View File

@ -0,0 +1,17 @@
use app::App;
use color_eyre::Result;
mod app;
mod errors;
mod tui;
mod ui;
mod widgets;
fn main() -> Result<()> {
errors::install_hooks()?;
let mut terminal = tui::init()?;
let app = &mut App::new();
app.run(&mut terminal)?;
tui::restore()?;
Ok(())
}

17
src/tui.rs Normal file
View File

@ -0,0 +1,17 @@
use crossterm::{execute, terminal::*};
use ratatui::prelude::*;
use std::io::{self, stdout, Stdout};
pub type Tui = Terminal<CrosstermBackend<Stdout>>;
pub fn init() -> io::Result<Tui> {
execute!(stdout(), EnterAlternateScreen)?;
enable_raw_mode()?;
Terminal::new(CrosstermBackend::new(stdout()))
}
pub fn restore() -> io::Result<()> {
execute!(stdout(), LeaveAlternateScreen)?;
disable_raw_mode()?;
Ok(())
}

46
src/ui.rs Normal file
View File

@ -0,0 +1,46 @@
use ratatui::prelude::*;
use crate::app::App;
use crate::widgets::add_new::AddNew;
use crate::widgets::instructions::Instructions;
use crate::widgets::left_pane::LeftPane;
use crate::widgets::right_pane::RightPane;
use crate::widgets::title::TitleWidget;
#[derive(Default)]
pub struct Ui {}
impl Ui {
pub fn build(&self, frame: &mut Frame, app: &mut App) {
let container = Layout::default()
.direction(Direction::Horizontal)
.constraints(vec![
Constraint::Min(0),
Constraint::Max(100),
Constraint::Min(0),
])
.split(frame.size());
// layout containing a top middle and bottom panel
let main_layout = Layout::default()
.direction(Direction::Vertical)
.constraints(vec![
Constraint::Length(2), // title
Constraint::Length(3), // add new
Constraint::Min(2), // dual panes + add new
Constraint::Length(2), // instructions
])
.split(container[1]);
let todo_panes = Layout::default()
.direction(Direction::Horizontal)
.constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
.split(main_layout[2]);
TitleWidget::default().create(frame, main_layout[0]);
AddNew::default().create(frame, main_layout[1], app);
Instructions::default().create(frame, main_layout[3], app);
LeftPane::default().create(frame, todo_panes[0], app);
RightPane::default().create(frame, todo_panes[1], app);
}
}

30
src/widgets/add_new.rs Normal file
View File

@ -0,0 +1,30 @@
use ratatui::prelude::*;
use ratatui::widgets::block::{Position, Title};
use ratatui::widgets::{Block, BorderType, Borders, Paragraph};
use crate::app::App;
#[derive(Default)]
pub struct AddNew {}
impl AddNew {
pub fn create(self, frame: &mut Frame, area: Rect, app: &App) {
let active_style = match app.adding_new {
true => Style::default().fg(Color::LightGreen),
false => Style::default(),
};
let add_new_block = Block::new()
.title(if app.adding_new {
Title::from(" New Todo ".bold())
} else {
Title::from(" New Todo ")
})
.title_position(Position::Top)
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.border_style(active_style);
let add_new_final = Paragraph::new(app.new_value.clone()).block(add_new_block);
frame.render_widget(add_new_final, area);
}
}

View File

@ -0,0 +1,49 @@
use ratatui::prelude::*;
use ratatui::widgets::Paragraph;
use crate::app::{App, Pane};
#[derive(Default)]
pub struct Instructions {}
impl Instructions {
pub fn create(self, frame: &mut Frame, area: Rect, app: &App) {
let instructions = match app.adding_new {
false => Self::create_add_new_instructions(app),
true => Self::create_normal_instructions(),
};
let text = Line::from(instructions);
let instructions_final = Paragraph::new(text).style(Style::default());
frame.render_widget(instructions_final, area);
}
fn create_add_new_instructions(app: &App) -> Vec<Span<'static>> {
vec![
" Quit ".into(),
"<Q> ".blue().bold(),
" Add Task ".into(),
"<A> ".blue().bold(),
" Up/Down ".into(),
"<J/K> ".blue().bold(),
" Left/Right".into(),
"<H/L> ".blue().bold(),
if app.pane_in_focus == Pane::Todo {
" Complete Item ".into()
} else {
" Undo Item ".into()
},
"<Enter> ".blue().bold(),
" Delete Item ".into(),
"<D> ".blue().bold(),
]
}
fn create_normal_instructions() -> Vec<Span<'static>> {
vec![
" Exit Add Mode ".into(),
"<esc> ".blue().bold(),
" Submit Task ".into(),
"<enter> ".blue().bold(),
]
}
}

56
src/widgets/left_pane.rs Normal file
View File

@ -0,0 +1,56 @@
use ratatui::prelude::*;
use ratatui::widgets::block::Title;
use ratatui::widgets::{Block, BorderType, Borders, List};
use crate::app::{App, Pane};
#[derive(Default)]
pub struct LeftPane {}
impl LeftPane {
pub fn create(self, frame: &mut Frame, area: Rect, app: &App) {
let focus_style = match app.pane_in_focus {
Pane::Todo if app.adding_new == false => Style::default().fg(Color::LightGreen),
_ => Style::default(),
};
let left_pane = Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.title(if app.pane_in_focus == Pane::Todo {
Title::from(" Today ".bold())
} else {
Title::from(" Today ")
})
.title_alignment(Alignment::Center)
.border_style(focus_style);
let items = app
.todos
.items
.clone()
.into_iter()
.enumerate()
.map(|(_i, item)| {
let style = match app.todos.state.selected() {
Some(i) => match app.pane_in_focus {
Pane::Todo => {
if i == _i {
Style::new().fg(Color::LightBlue).bg(Color::Blue)
} else {
Style::default()
}
}
_ => Style::default(),
},
None => Style::default(),
};
Text::styled(format!("{}", item), style)
});
let left_pane_content = List::new(items).block(left_pane);
// Create a List from all list items and highlight the currently selected one
frame.render_widget(left_pane_content, area);
}
}

5
src/widgets/mod.rs Normal file
View File

@ -0,0 +1,5 @@
pub(crate) mod add_new;
pub(crate) mod instructions;
pub(crate) mod left_pane;
pub(crate) mod right_pane;
pub(crate) mod title;

58
src/widgets/right_pane.rs Normal file
View File

@ -0,0 +1,58 @@
use ratatui::prelude::*;
use ratatui::widgets::block::Title;
use ratatui::widgets::{Block, BorderType, Borders, List};
use crate::app::{App, Pane};
#[derive(Default)]
pub struct RightPane {}
impl RightPane {
pub fn create(self, frame: &mut Frame, area: Rect, app: &mut App) {
let focus_style = match app.pane_in_focus {
Pane::Completed if app.adding_new == false => Style::default().fg(Color::LightGreen),
_ => Style::default(),
};
let yesterday_pane = Block::default()
.title(if app.pane_in_focus == Pane::Completed {
Title::from(" Yesterday ".bold())
} else {
Title::from(" Yesterday ")
})
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.title_alignment(Alignment::Center)
.border_style(focus_style);
if app.completed.items.len() > 0 && app.completed.state.selected().is_none() {
app.completed.state.select(Some(0));
}
let items = app
.completed
.items
.clone()
.into_iter()
.enumerate()
.map(|(_i, item)| {
let style = match app.completed.state.selected() {
Some(i) => match app.pane_in_focus {
Pane::Completed => {
if i == _i {
Style::new().fg(Color::LightBlue).bg(Color::Blue)
} else {
Style::default()
}
}
_ => Style::default(),
},
None => Style::default(),
};
Text::styled(format!("{}", item), style)
});
let right_pane_content = List::new(items).block(yesterday_pane);
frame.render_widget(right_pane_content, area);
}
}

20
src/widgets/title.rs Normal file
View File

@ -0,0 +1,20 @@
use ratatui::prelude::*;
use ratatui::widgets::block::{Position, Title};
use ratatui::widgets::Block;
#[derive(Default)]
pub struct TitleWidget {}
impl TitleWidget {
pub fn create(self, frame: &mut Frame, area: Rect) {
frame.render_widget(&self, area);
}
}
impl Widget for &TitleWidget {
fn render(self, area: Rect, buf: &mut Buffer) {
let _ = Block::new()
.title(Title::from(" Daily Standup ".bold()))
.title_position(Position::Top)
.title_alignment(Alignment::Center)
.render(area, buf);
}
}