~rjarry/aerc

ee00257017f509839e3c656cdba38e7655ad99d8 — Robin Jarry a month ago 05c5dcd rust
wip

Signed-off-by: Robin Jarry <robin@jarry.cc>
M .gitignore => .gitignore +1 -0
@@ 6,6 6,7 @@
/colorize
/.aerc.d
/linters.so
/target
race.log.*
raw.log
*.1

A Cargo.lock => Cargo.lock +960 -0
@@ 0,0 1,960 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "addr2line"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
dependencies = [
 "gimli",
]

[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"

[[package]]
name = "aerc"
version = "0.20.0"
dependencies = [
 "anyhow",
 "bitflags",
 "clap",
 "configparser",
 "crossterm",
 "derivative",
 "futures",
 "gtmpl",
 "log",
 "simple_logger",
 "time",
 "tokio",
 "tui",
]

[[package]]
name = "anyhow"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
dependencies = [
 "backtrace",
]

[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
 "hermit-abi 0.1.19",
 "libc",
 "winapi",
]

[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"

[[package]]
name = "backtrace"
version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
dependencies = [
 "addr2line",
 "cc",
 "cfg-if",
 "libc",
 "miniz_oxide",
 "object",
 "rustc-demangle",
]

[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"

[[package]]
name = "bytes"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"

[[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.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"

[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "clap"
version = "4.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
dependencies = [
 "bitflags",
 "clap_derive",
 "clap_lex",
 "is-terminal",
 "once_cell",
 "strsim",
 "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 = "configparser"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5458d9d1a587efaf5091602c59d299696a3877a439c8f6d461a2d3cce11df87a"
dependencies = [
 "indexmap",
]

[[package]]
name = "crossterm"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
dependencies = [
 "bitflags",
 "crossterm_winapi",
 "futures-core",
 "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 = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
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]]
name = "futures"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
dependencies = [
 "futures-channel",
 "futures-core",
 "futures-executor",
 "futures-io",
 "futures-sink",
 "futures-task",
 "futures-util",
]

[[package]]
name = "futures-channel"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
dependencies = [
 "futures-core",
 "futures-sink",
]

[[package]]
name = "futures-core"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"

[[package]]
name = "futures-executor"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
dependencies = [
 "futures-core",
 "futures-task",
 "futures-util",
]

[[package]]
name = "futures-io"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"

[[package]]
name = "futures-macro"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "futures-sink"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"

[[package]]
name = "futures-task"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"

[[package]]
name = "futures-util"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
dependencies = [
 "futures-channel",
 "futures-core",
 "futures-io",
 "futures-macro",
 "futures-sink",
 "futures-task",
 "memchr",
 "pin-project-lite",
 "pin-utils",
 "slab",
]

[[package]]
name = "gimli"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec"

[[package]]
name = "gtmpl"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b924c0ea1149cd5cc9b208b33a4acb036ffb4b39c10048569de20616988a2b4"
dependencies = [
 "anyhow",
 "gtmpl_value",
 "lazy_static",
 "percent-encoding",
 "thiserror",
]

[[package]]
name = "gtmpl_value"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d61bf6605eabca491ef6db6ed194e0aa82900ccc8bdea4c56ac277102152dd5"
dependencies = [
 "anyhow",
 "thiserror",
]

[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"

[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"

[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
 "libc",
]

[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
 "libc",
]

[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"

[[package]]
name = "indexmap"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
 "autocfg",
 "hashbrown",
]

[[package]]
name = "io-lifetimes"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
dependencies = [
 "libc",
 "windows-sys 0.45.0",
]

[[package]]
name = "is-terminal"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
dependencies = [
 "hermit-abi 0.3.1",
 "io-lifetimes",
 "rustix",
 "windows-sys 0.45.0",
]

[[package]]
name = "itoa"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"

[[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.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"

[[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.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
 "cfg-if",
]

[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"

[[package]]
name = "miniz_oxide"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [
 "adler",
]

[[package]]
name = "mio"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
dependencies = [
 "libc",
 "log",
 "wasi",
 "windows-sys 0.42.0",
]

[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
 "hermit-abi 0.2.6",
 "libc",
]

[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
 "libc",
]

[[package]]
name = "object"
version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
dependencies = [
 "memchr",
]

[[package]]
name = "once_cell"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"

[[package]]
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 = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
 "lock_api",
 "parking_lot_core",
]

[[package]]
name = "parking_lot_core"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
dependencies = [
 "cfg-if",
 "libc",
 "redox_syscall",
 "smallvec",
 "windows-sys 0.45.0",
]

[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"

[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"

[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"

[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
 "proc-macro-error-attr",
 "proc-macro2",
 "quote",
 "syn",
 "version_check",
]

[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
 "proc-macro2",
 "quote",
 "version_check",
]

[[package]]
name = "proc-macro2"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
 "bitflags",
]

[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"

[[package]]
name = "rustix"
version = "0.36.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
dependencies = [
 "bitflags",
 "errno",
 "io-lifetimes",
 "libc",
 "linux-raw-sys",
 "windows-sys 0.45.0",
]

[[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.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"

[[package]]
name = "signal-hook"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
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.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
dependencies = [
 "libc",
]

[[package]]
name = "simple_logger"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e190a521c2044948158666916d9e872cbb9984f755e9bb3b5b75a836205affcd"
dependencies = [
 "atty",
 "log",
 "time",
 "windows-sys 0.42.0",
]

[[package]]
name = "slab"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
dependencies = [
 "autocfg",
]

[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"

[[package]]
name = "socket2"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
dependencies = [
 "libc",
 "winapi",
]

[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"

[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-ident",
]

[[package]]
name = "termcolor"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
 "winapi-util",
]

[[package]]
name = "thiserror"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
 "thiserror-impl",
]

[[package]]
name = "thiserror-impl"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "time"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
dependencies = [
 "itoa",
 "libc",
 "num_threads",
 "serde",
 "time-core",
 "time-macros",
]

[[package]]
name = "time-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"

[[package]]
name = "time-macros"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
dependencies = [
 "time-core",
]

[[package]]
name = "tokio"
version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
dependencies = [
 "autocfg",
 "bytes",
 "libc",
 "memchr",
 "mio",
 "num_cpus",
 "parking_lot",
 "pin-project-lite",
 "signal-hook-registry",
 "socket2",
 "tokio-macros",
 "windows-sys 0.42.0",
]

[[package]]
name = "tokio-macros"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "tui"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1"
dependencies = [
 "bitflags",
 "cassowary",
 "crossterm",
 "unicode-segmentation",
 "unicode-width",
]

[[package]]
name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"

[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"

[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"

[[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-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-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
 "windows-targets",
]

[[package]]
name = "windows-targets"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
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"

A Cargo.toml => Cargo.toml +34 -0
@@ 0,0 1,34 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2023 Robin Jarry

[package]
name = "aerc"
version = "0.20.0"
edition = "2021"
authors = ["Robin Jarry <robin@jarry.cc>"]
description = "A pretty good email client"
readme = "README.md"
homepage = "https://aerc-mail.org/"
repository = "https://git.sr.ht/~rjarry/aerc"
license = "MIT"

[dependencies]
anyhow = { version = "1.0.69", features = ["backtrace"] }
bitflags = "1.3.2"
clap = { version = "4.1.4", features = ["derive", "env"] }
configparser = { version = "3.0.2", features = ["indexmap"] }
crossterm = { version = "0.25.0", features = ["event-stream"] }
derivative = "2.2.0"
futures = "0.3.26"
gtmpl = "0.7.1"
log = "0.4.17"
simple_logger = { version = "4.0.0", default-features = false, features = ["time", "timestamps"] }
time = "0.3.17"
tokio = { version = "1.25.0", features = ["full"] }
tui = "0.19.0"

[profile.release]
lto = true
codegen-units = 1
strip = true
debug-assertions = false

A src/app/mod.rs => src/app/mod.rs +61 -0
@@ 0,0 1,61 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use std::collections::HashMap;
use std::sync::Arc;

use tokio::sync::mpsc::channel;
use tokio::sync::mpsc::Receiver;
use tokio::sync::mpsc::Sender;
use tokio::sync::Mutex;
use tokio::task::JoinHandle;

use crate::config::AccountConfig;
use crate::config::Config;
use crate::worker::Worker;
use crate::worker::WorkerMessage;

pub struct App {
    config: Arc<Mutex<Config>>,
    worker_tasks: Vec<JoinHandle<()>>,
    to_workers: HashMap<String, Sender<WorkerMessage>>,
    from_workers: HashMap<String, Receiver<WorkerMessage>>,
    // app internal state change notifications for UI
    updates: Sender<()>,
}

impl App {
    pub fn new(config: Arc<Mutex<Config>>, updates: Sender<()>) -> Self {
        App {
            config,
            updates,
            worker_tasks: Vec::new(),
            to_workers: HashMap::new(),
            from_workers: HashMap::new(),
        }
    }

    pub fn invalidate(&self) {
        // ignore if a pending tick is already present in the channel
        let _ = self.updates.try_send(());
    }

    pub fn start_worker(&mut self, config: AccountConfig) {
        let (from_worker_tx, from_worker_rx) = channel::<WorkerMessage>(32);
        let (to_worker_tx, to_worker_rx) = channel::<WorkerMessage>(32);

        self.to_workers.insert(config.name.clone(), to_worker_tx);
        self.from_workers
            .insert(config.name.clone(), from_worker_rx);

        let handle = tokio::spawn(async move {
            let worker = Worker::new(config, to_worker_rx, from_worker_tx);
            let run = worker.run();
            tokio::pin!(run);
            run.await;
        });
        self.worker_tasks.push(handle);
    }

    pub async fn stop_workers(&self) {}
}

A src/cmd/mod.rs => src/cmd/mod.rs +4 -0
@@ 0,0 1,4 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

pub trait Command {}

A src/config/accounts.rs => src/config/accounts.rs +17 -0
@@ 0,0 1,17 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

#[derive(Debug, Default, Clone)]
pub struct AccountConfig {
    pub name: String,
    pub backend: BackendType,
}

#[derive(Debug, Default, Clone)]
pub enum BackendType {
    #[default]
    IMAP,
    Maildir,
    Mbox,
    Notmuch,
}

A src/config/columns.rs => src/config/columns.rs +29 -0
@@ 0,0 1,29 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use bitflags::bitflags;
use derivative::Derivative;
use gtmpl::Template;

#[derive(Derivative)]
#[derivative(Debug, Default)]
pub struct ColumnDef {
    pub name: String,
    pub flags: ColumnFlags,
    pub width: f64,
    #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
    pub template: Template,
}

bitflags! {
    #[derive(Default)]
    pub struct ColumnFlags: u8 {
        const ALIGN_LEFT = 1 << 0;
        const ALIGN_CENTER = 1 << 1;
        const ALIGN_RIGHT = 1 << 2 ;
        const WIDTH_AUTO = 1 << 3 ; // whatever is left
        const WIDTH_FRACTION = 1 << 4; // ratio of total width
        const WIDTH_EXACT = 1 << 5; // exact number of characters
        const WIDTH_FIT = 1 << 6; // fit to column content width
    }
}

A src/config/mod.rs => src/config/mod.rs +31 -0
@@ 0,0 1,31 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

mod accounts;
mod columns;
mod style;
mod templates;
mod ui;

use std::collections::HashMap;

use anyhow::Result;
use derivative::Derivative;

pub use crate::config::accounts::AccountConfig;
pub use crate::config::accounts::BackendType;
pub use crate::config::ui::UiConfig;

#[derive(Derivative)]
#[derivative(Debug, Default)]
pub struct Config {
    pub ui: UiConfig,
    pub accounts: HashMap<String, AccountConfig>,
}

impl Config {
    pub fn parse(accounts: Vec<String>) -> Result<Self> {
        let c = Self::default();
        Ok(c)
    }
}

A src/config/style.rs => src/config/style.rs +5 -0
@@ 0,0 1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

#[derive(Debug, Default)]
pub struct StyleSet {}

A src/config/templates.rs => src/config/templates.rs +10 -0
@@ 0,0 1,10 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use std::fmt;

use gtmpl::Template;

pub fn debug_template(t: &Template, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    f.write_fmt(format_args!("Template({:?})", t.text))
}

A src/config/ui.rs => src/config/ui.rs +99 -0
@@ 0,0 1,99 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use std::collections::HashMap;

use derivative::Derivative;
use gtmpl::Template;

use crate::config::columns::ColumnDef;
use crate::config::style::StyleSet;

#[derive(Derivative)]
#[derivative(Debug, Default)]
pub struct UiConfig {
    // message list
    pub index_columns: Vec<ColumnDef>,
    pub column_separator: String,
    pub empty_message: String,
    pub threading_enabled: bool,
    pub force_client_threads: bool,
    pub client_threads_delay: time::Duration,
    pub sort: Vec<String>,
    pub reverse_order: bool,
    pub reverse_thread_order: bool,
    pub sort_thread_siblings: bool,

    // dirlist
    #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
    pub dirlist_left: Template,
    #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
    pub dirlist_right: Template,
    pub sidebar_width: u8,
    pub empty_dirlist: String,
    pub dirlist_delay: time::Duration,
    pub dirlist_tree: bool,
    pub dirlist_collapse: u8,

    // time formats
    pub timestamp_format: String,
    pub this_day_time_format: String,
    pub this_week_time_format: String,
    pub this_year_time_format: String,
    pub msgview_timestamp_format: String,
    pub msgview_this_day_time_format: String,
    pub msgview_this_week_time_format: String,
    pub msgview_this_year_time_format: String,

    // icons
    pub icon_unencrypted: String,
    pub icon_encrypted: String,
    pub icon_signed: String,
    pub icon_signed_encrypted: String,
    pub icon_unknown: String,
    pub icon_invalid: String,
    pub icon_attachment: String,

    // style
    pub stylesets_dirs: Vec<String>,
    pub styleset_name: String,
    style: StyleSet,

    // general appearance
    pub border_vertical: char,
    pub border_horizontal: char,
    pub spinner: String,
    pub spinner_delimiter: String,
    pub spinner_interval: time::Duration,
    pub pinned_tab_marker: String,

    // behaviour
    pub automark_read: bool,
    pub next_message_on_delete: bool,
    pub mouse_enabled: bool,
    pub fuzzy_complete: bool,
    pub new_message_bell: bool,
    pub completion_delay: time::Duration,
    pub completion_min_chars: u8,
    pub completion_popovers: bool,

    // tabs
    #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
    pub tab_title_account: Template,
    #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
    pub tab_title_composer: Template,

    // contextual
    contextual_sections: Vec<UiContext>,
    contextual_counts: HashMap<UiContextType, usize>,
    contextual_cache: HashMap<UiContextKey, UiConfig>,
}

#[derive(Debug)]
struct UiContext {}

#[derive(Debug)]
enum UiContextType {}

#[derive(Debug)]
struct UiContextKey {}

A src/main.rs => src/main.rs +142 -0
@@ 0,0 1,142 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

mod app;
mod cmd;
mod config;
mod worker;

use std::io;
use std::panic;
use std::sync::Arc;

use anyhow::Result;
use clap::Parser;
use crossterm::cursor;
use crossterm::event::DisableMouseCapture;
use crossterm::event::EnableMouseCapture;
use crossterm::event::Event;
use crossterm::event::EventStream;
use crossterm::event::KeyCode;
use crossterm::event::KeyEventKind;
use crossterm::terminal::disable_raw_mode;
use crossterm::terminal::enable_raw_mode;
use crossterm::terminal::EnterAlternateScreen;
use crossterm::terminal::LeaveAlternateScreen;
use crossterm::terminal::SetTitle;
use crossterm::ExecutableCommand;
use futures::future::FutureExt;
use futures::StreamExt;
use tokio::sync::mpsc::channel;
use tokio::sync::mpsc::Receiver;
use tokio::sync::Mutex;
use tui::backend::Backend;
use tui::backend::CrosstermBackend;
use tui::Terminal;

use crate::app::App;
use crate::config::Config;

/// A pretty good email client
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// Enabled account (by default, all accounts are enabled).
    #[arg(short, long = "account", env = "AERC_ACCOUNTS")]
    accounts: Vec<String>,
}

#[tokio::main]
async fn main() -> Result<()> {
    let default_hook = panic::take_hook();
    panic::set_hook(Box::new(move |info| {
        restore_term().unwrap();
        default_hook(info);
    }));

    // Parse command line arguments and configuration files.
    let args = Args::parse();
    let config = Arc::new(Mutex::new(Config::parse(args.accounts)?));
    let (updates_tx, updates_rx) = channel(1);
    let app = Arc::new(Mutex::new(App::new(config.clone(), updates_tx)));

    // Start email handling workers in the background.
    for account in config.lock().await.accounts.values() {
        app.lock().await.start_worker(account.clone());
    }

    // The UI must run in the "main" thread.
    ui_loop(config, app.clone(), updates_rx).await?;

    app.lock().await.stop_workers().await;

    restore_term()?;

    Ok(())
}

async fn ui_loop(
    config: Arc<Mutex<Config>>,
    app: Arc<Mutex<App>>,
    mut app_updates: Receiver<()>,
) -> Result<()> {
    // Terminal initialization.
    enable_raw_mode()?;

    let mut backend = CrosstermBackend::new(io::stdout());

    backend.execute(EnterAlternateScreen)?;
    if config.lock().await.ui.mouse_enabled {
        backend.execute(EnableMouseCapture)?;
    }
    backend.hide_cursor()?;
    backend.execute(SetTitle("aerc"))?;

    let terminal = Terminal::new(backend)?;

    let mut term_events = EventStream::new();

    loop {
        // TODO: draw ui here
        tokio::select!(
            t = app_updates.recv() => match t {
                Some(_) => (),
                None => break,
            },
            e = term_events.next().fuse() => match e {
                Some(Ok(event)) => match event {
                    Event::Key(key) => {
                        if key.kind == KeyEventKind::Press {
                            println!("key {:?}\r", key);
                            if key.code == KeyCode::Esc {
                                break;
                            }
                        }
                    }
                    Event::Mouse(mouse) => {
                        println!("mouse {:?}\r", mouse);
                    }
                    Event::Paste(buf) => {
                        println!("paste {:?}\r", buf);
                    }
                    _ => ()
                }
                Some(Err(e)) => println!("Error: {:?}\r", e),
                None => break,
            }
        );
    }

    Ok(())
}

fn restore_term() -> Result<()> {
    crossterm::execute!(
        io::stdout(),
        LeaveAlternateScreen,
        DisableMouseCapture,
        cursor::Show
    )?;
    disable_raw_mode()?;
    Ok(())
}

A src/worker/imap/mod.rs => src/worker/imap/mod.rs +12 -0
@@ 0,0 1,12 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use crate::worker::Backend;

pub struct IMAPBackend {}

pub fn new() -> IMAPBackend {
    IMAPBackend {}
}

impl Backend for IMAPBackend {}

A src/worker/maildir/mod.rs => src/worker/maildir/mod.rs +12 -0
@@ 0,0 1,12 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use crate::worker::Backend;

pub struct MaildirBackend {}

pub fn new() -> MaildirBackend {
    MaildirBackend {}
}

impl Backend for MaildirBackend {}

A src/worker/mbox/mod.rs => src/worker/mbox/mod.rs +12 -0
@@ 0,0 1,12 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use crate::worker::Backend;

pub struct MboxBackend {}

pub fn new() -> MboxBackend {
    MboxBackend {}
}

impl Backend for MboxBackend {}

A src/worker/mod.rs => src/worker/mod.rs +46 -0
@@ 0,0 1,46 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

mod imap;
mod maildir;
mod mbox;
mod notmuch;

use tokio::sync::mpsc::Receiver;
use tokio::sync::mpsc::Sender;

use crate::config::AccountConfig;
use crate::config::BackendType;

pub struct Worker {
    config: AccountConfig,
    backend: Box<dyn Backend>,
    from_app: Receiver<WorkerMessage>,
    to_app: Sender<WorkerMessage>,
}

impl Worker {
    pub fn new(
        config: AccountConfig,
        from_app: Receiver<WorkerMessage>,
        to_app: Sender<WorkerMessage>,
    ) -> Self {
        let backend: Box<dyn Backend> = match config.backend {
            BackendType::IMAP => Box::new(imap::new()),
            BackendType::Maildir => Box::new(maildir::new()),
            BackendType::Mbox => Box::new(mbox::new()),
            BackendType::Notmuch => Box::new(notmuch::new()),
        };
        Worker {
            config,
            backend,
            from_app,
            to_app,
        }
    }

    pub async fn run(self) {}
}

pub trait Backend: Send + Sync {}
pub struct WorkerMessage {}

A src/worker/notmuch/mod.rs => src/worker/notmuch/mod.rs +12 -0
@@ 0,0 1,12 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Robin Jarry

use crate::worker::Backend;

pub struct NotmuchBackend {}

pub fn new() -> NotmuchBackend {
    NotmuchBackend {}
}

impl Backend for NotmuchBackend {}