diff --git a/Cargo.lock b/Cargo.lock index 9ff77ce..c8c815e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,28 +32,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "advisory-lock" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6caee7d48f930f9ad3fc9546f8cbf843365da0c5b0ca4eee1d1ac3dd12d8f93" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if", - "cipher 0.3.0", - "cpufeatures", - "opaque-debug", -] - [[package]] name = "aes" version = "0.8.4" @@ -61,7 +39,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher 0.4.4", + "cipher", "cpufeatures", ] @@ -72,7 +50,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", "once_cell", "version_check", "zerocopy", @@ -116,47 +93,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -184,51 +162,16 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d4d23bcc79e27423727b36823d86233aad06dfea531837b038394d11e9928" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 5.3.0", - "event-listener-strategy 0.5.1", + "event-listener-strategy", "futures-core", "pin-project-lite", ] -[[package]] -name = "async-ctrlc" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907279f6e91a51c8ec7cac24711e8308f21da7c10c7700ca2f7e125694ed2df1" -dependencies = [ - "ctrlc", -] - -[[package]] -name = "async-executor" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b10202063978b3351199d68f8b22c4e47e4b1b822f8d43fd862d5ea8c006b29a" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand 2.0.2", - "futures-lite 2.3.0", - "slab", -] - -[[package]] -name = "async-fs" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "blocking", - "futures-lite 1.13.0", -] - [[package]] name = "async-io" version = "1.13.0" @@ -251,18 +194,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.6.0", - "rustix 0.38.32", + "polling 3.7.2", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -279,12 +222,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", + "event-listener 5.3.1", + "event-listener-strategy", "pin-project-lite", ] @@ -301,54 +244,54 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "async-recursion" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" dependencies = [ - "async-io 2.3.2", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.32", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "async-task" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -359,15 +302,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "aws-lc-rs" -version = "1.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8487b59d62764df8231cb371c459314df895b41756df457a1fb1243d65c89195" +checksum = "4ae74d9bd0a7530e8afd1770739ad34b36838829d6ad61818f9230f683f5ad77" dependencies = [ "aws-lc-sys", "mirai-annotations", @@ -377,9 +320,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.16.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15eb61145320320eb919d9bab524617a7aa4216c78d342fae3a758bc33073e4" +checksum = "0f0e249228c6ad2d240c2dc94b714d711629d52bad946075d8e9b2f5391f0703" dependencies = [ "bindgen", "cc", @@ -425,9 +368,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -441,7 +384,7 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cexpr", "clang-sys", "itertools", @@ -454,7 +397,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.59", + "syn 2.0.72", "which", ] @@ -472,15 +415,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -491,22 +428,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-modes" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" -dependencies = [ - "block-padding 0.2.1", - "cipher 0.3.0", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "block-padding" version = "0.3.3" @@ -518,18 +439,15 @@ dependencies = [ [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ "async-channel", - "async-lock 3.3.0", "async-task", - "fastrand 2.0.2", "futures-io", "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] @@ -539,45 +457,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ "byteorder", - "cipher 0.4.4", + "cipher", ] [[package]] name = "bounded-static" -version = "0.5.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2325bd33fa7e3018e7e37f5b0591ba009124963b5a3f8b7cae6d0a8c1028ed4" -dependencies = [ - "bounded-static-derive", -] +checksum = "0beb903daa49b43bcafb5d5eebe633f9ad638d8b16cd08f95fb05ee7bd099321" [[package]] name = "bounded-static-derive" -version = "0.5.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f10dd247355bf631d98d2753d87ae62c84c8dcb996ad9b24a4168e0aec29bd6b" +checksum = "e0af050e27e5d57aa14975f97fe47a134c46a390f91819f23a625319a7111bfa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "bstr" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.6", + "regex-automata 0.4.7", "serde", ] [[package]] name = "buffer-redux" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9f8ddd22e0a12391d1e7ada69ec3b0da1914f1cec39c5cf977143c5b2854f5" +checksum = "4e8acf87c5b9f5897cd3ebb9a327f420e0cae9dd4e5c1d2e36f2c84c571a58f1" dependencies = [ "memchr", ] @@ -602,30 +517,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" - -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "camellia" @@ -634,7 +528,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3264e2574e9ef2b53ce6f536dea83a69ac0bc600b762d1523ff83fe07230ce30" dependencies = [ "byteorder", - "cipher 0.4.4", + "cipher", ] [[package]] @@ -643,14 +537,23 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b07d673db1ccf000e90f54b819db9e75a8348d6eb056e9b8ab53231b7a9911" dependencies = [ - "cipher 0.4.4", + "cipher", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", ] [[package]] name = "cc" -version = "1.0.94" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549" dependencies = [ "jobserver", "libc", @@ -671,7 +574,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -690,12 +593,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "chrono" version = "0.4.38" @@ -708,7 +605,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -723,15 +620,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - [[package]] name = "cipher" version = "0.4.4" @@ -744,9 +632,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -755,9 +643,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36" dependencies = [ "clap_builder", "clap_derive", @@ -765,9 +653,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed" dependencies = [ "anstream", "anstyle", @@ -778,36 +666,36 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.2" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" +checksum = "aa3c596da3cf0983427b0df0dba359df9182c13bd5b519b585a482b0c351f4e8" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clap_mangen" -version = "0.2.20" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1dd95b5ebb5c1c54581dd6346f3ed6a79a3eef95dd372fc2ac13d535535300e" +checksum = "f17415fd4dfbea46e3274fcd8d368284519b358654772afb700dc2e8d2b24eeb" dependencies = [ "clap", "roff", @@ -851,9 +739,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "comfy-table" @@ -869,9 +757,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -895,12 +783,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "conv" version = "0.3.3" @@ -910,12 +792,6 @@ dependencies = [ "custom_derive", ] -[[package]] -name = "convert_case" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" - [[package]] name = "core-foundation" version = "0.9.4" @@ -949,9 +825,9 @@ checksum = "fd121741cf3eb82c08dd3023eb55bf2665e5f60ec20f89760cf836ae4562e6a0" [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -977,9 +853,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossterm" @@ -990,8 +866,8 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", - "parking_lot 0.12.1", + "mio 0.8.11", + "parking_lot 0.12.3", "signal-hook", "signal-hook-mio", "winapi", @@ -1003,11 +879,11 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm_winapi", "libc", - "mio", - "parking_lot 0.12.1", + "mio 0.8.11", + "parking_lot 0.12.3", "signal-hook", "signal-hook-mio", "winapi", @@ -1054,28 +930,17 @@ dependencies = [ "memchr", ] -[[package]] -name = "ctrlc" -version = "3.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" -dependencies = [ - "nix 0.28.0", - "windows-sys 0.52.0", -] - [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -1089,7 +954,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -1170,9 +1035,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "der" @@ -1185,15 +1050,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - [[package]] name = "derivative" version = "2.2.0" @@ -1242,7 +1098,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -1275,16 +1131,6 @@ dependencies = [ "dirs-sys 0.4.1", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.7" @@ -1308,22 +1154,11 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" @@ -1371,9 +1206,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1399,30 +1234,27 @@ dependencies = [ [[package]] name = "email-lib" version = "0.24.1" -source = "git+https://git.sr.ht/~soywod/pimalaya#a28e746a634c066f4b9b0b15cd6f742fa530164d" dependencies = [ - "advisory-lock", - "async-ctrlc", "async-trait", "chrono", "chumsky", - "convert_case", - "dirs 4.0.0", "email-macros", "email_address", "futures", "hickory-resolver", - "hyper", - "hyper-rustls", + "http-body-util", + "hyper 1.4.1", + "hyper-rustls 0.27.2", + "hyper-util", "imap-client", + "imap-next", "keyring-lib", "mail-builder", "mail-parser", "mail-send", - "maildirpp", + "maildirs", "mml-lib", "notify", - "notify-rust", "notmuch", "oauth-lib", "once_cell", @@ -1439,7 +1271,7 @@ dependencies = [ "shellexpand-utils", "thiserror", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls 0.26.0", "tracing", "tree_magic_mini", "urlencoding", @@ -1453,14 +1285,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f24a09fd651027f8764f8a12c12358715cb9bab622ab3125ede3dd6ae047c95" dependencies = [ "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "email_address" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" dependencies = [ "serde", ] @@ -1489,14 +1321,14 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -1504,13 +1336,13 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -1530,9 +1362,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1557,20 +1389,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "4.0.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -1579,21 +1400,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" -dependencies = [ - "event-listener 5.3.0", + "event-listener 5.3.1", "pin-project-lite", ] @@ -1618,9 +1429,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "ff" @@ -1634,20 +1445,20 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] @@ -1658,9 +1469,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -1787,10 +1598,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.2", "futures-core", - "futures-io", - "parking", "pin-project-lite", ] @@ -1802,7 +1610,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -1876,9 +1684,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1962,7 +1770,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1972,9 +1799,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -1998,6 +1825,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -2006,9 +1839,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hickory-proto" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091a6fbccf4860009355e3efc52ff4acf37a63489aad7435372d44ceeb6fbbcf" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" dependencies = [ "async-trait", "cfg-if", @@ -2021,8 +1854,7 @@ dependencies = [ "ipnet", "once_cell", "rand", - "ring 0.16.20", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile 1.0.4", "thiserror", "tinyvec", @@ -2034,9 +1866,9 @@ dependencies = [ [[package]] name = "hickory-resolver" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" dependencies = [ "cfg-if", "futures-util", @@ -2044,10 +1876,10 @@ dependencies = [ "ipconfig", "lru-cache", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "resolv-conf", - "rustls 0.21.10", + "rustls 0.21.12", "smallvec", "thiserror", "tokio", @@ -2057,7 +1889,7 @@ dependencies = [ [[package]] name = "himalaya" -version = "1.0.0-beta.4" +version = "1.0.0" dependencies = [ "ariadne", "async-trait", @@ -2090,7 +1922,7 @@ dependencies = [ "terminal_size 0.1.17", "tokio", "toml", - "toml_edit 0.22.9", + "toml_edit 0.22.20", "tracing", "tracing-error", "tracing-subscriber", @@ -2148,6 +1980,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -2155,15 +1998,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2173,28 +2039,48 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.7", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -2202,15 +2088,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.30", "log", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", ] +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "log", + "rustls 0.23.12", + "rustls-native-certs 0.7.1", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -2240,7 +2165,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "075557004419d7f2031b8bb7f44bb43e55a83ca7b63076a8fb8fe75753836477" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -2272,13 +2197,12 @@ dependencies = [ [[package]] name = "imap-client" version = "0.1.0" -source = "git+https://github.com/soywod/imap-client.git#4533995f3ebe6efdb503128af15a867b60e48645" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e62726ad9db2962ab35df8bd5f1a113a5fa1edbece0f72bab621c0a3c7850b" dependencies = [ - "imap-flow", - "imap-types", + "imap-next", "once_cell", - "rustls-native-certs 0.7.0", - "tag-generator", + "rustls-native-certs 0.7.1", "thiserror", "tokio", "tokio-rustls 0.26.0", @@ -2287,29 +2211,27 @@ dependencies = [ [[package]] name = "imap-codec" -version = "2.0.0" -source = "git+https://github.com/duesee/imap-codec.git#638924e92d9a8ea82208397d8e739110296daf01" +version = "2.0.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "204c4816456f1a732d55bb42d90bac69538588dcdf3ef8c9a90b5ca02397021a" dependencies = [ "abnf-core", - "base64 0.21.7", - "bounded-static", + "base64 0.22.1", "chrono", "imap-types", "log", "nom", - "thiserror", ] [[package]] -name = "imap-flow" -version = "0.1.0" -source = "git+https://github.com/soywod/imap-flow?branch=into-inner-stream#b705adbc03976367330f2b24e99a9623e5da3733" +name = "imap-next" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3abfad92a1a0c7d424df1932c22a528c6ca9323d70c57a84617225a003cf9712" dependencies = [ - "bounded-static", "bytes", "imap-codec", - "imap-types", - "rustls 0.23.5", + "rustls 0.23.12", "thiserror", "tokio", "tokio-rustls 0.26.0", @@ -2318,12 +2240,15 @@ dependencies = [ [[package]] name = "imap-types" -version = "2.0.0" -source = "git+https://github.com/duesee/imap-codec.git#638924e92d9a8ea82208397d8e739110296daf01" +version = "2.0.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20a1a5a918696bcc51132d4b96f9dd872517e70fcb7a7b8082f0edcd83a84eeb" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bounded-static", + "bounded-static-derive", "chrono", + "rand", "thiserror", ] @@ -2335,9 +2260,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown", @@ -2382,16 +2307,17 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array", ] [[package]] name = "inquire" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe95f33091b9b7b517a5849bce4dce1b550b430fc20d58059fcaa319ed895d8b" +checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm 0.25.0", "dyn-clone", "fuzzy-matcher", @@ -2404,9 +2330,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2417,7 +2343,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -2428,7 +2354,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.6", + "socket2 0.5.7", "widestring", "windows-sys 0.48.0", "winreg 0.50.0", @@ -2440,6 +2366,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -2457,9 +2389,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -2484,9 +2416,9 @@ dependencies = [ [[package]] name = "keyring" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be8bc4c6b6e9d85ecdad090fcf342a9216f53d747a537cc05e3452fd650ca46" +checksum = "363387f0019d714aa60cc30ab4fe501a747f4c08fc58f069dd14be971bd495a0" dependencies = [ "lazy_static", "linux-keyutils", @@ -2495,9 +2427,9 @@ dependencies = [ [[package]] name = "keyring-lib" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2e6d01e57f1b382ba5a1c40ef866855e8bab15f7caa4033480db80a5b9b9aff" +checksum = "eb0a843c3edec50d5f5541e72c4068ab5bc273efa16b4ba51c5825a872ad8a9a" dependencies = [ "keyring", "log", @@ -2529,11 +2461,11 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -2544,9 +2476,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libgpg-error-sys" @@ -2561,12 +2493,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2581,8 +2513,9 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", + "redox_syscall 0.5.3", ] [[package]] @@ -2597,7 +2530,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -2609,15 +2542,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2625,9 +2558,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru-cache" @@ -2638,45 +2571,11 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "mac-notification-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fca4d74ff9dbaac16a01b924bc3693fa2bba0862c2c633abc73f9a8ea21f64" -dependencies = [ - "cc", - "dirs-next", - "objc-foundation", - "objc_id", - "time", -] - -[[package]] -name = "mail-auth" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e9759ecef5c0d048464fee80947ca5ef25faff98add10ea8787a6e195b8dc5f" -dependencies = [ - "ahash", - "flate2", - "hickory-resolver", - "lru-cache", - "mail-builder", - "mail-parser", - "parking_lot 0.12.1", - "quick-xml 0.31.0", - "ring 0.17.8", - "rustls-pemfile 2.1.2", - "serde", - "serde_json", - "zip", -] - [[package]] name = "mail-builder" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef70f53409852d2612f2249810cbbe0c9931ca25b739b734bafc7f61d88051d4" +checksum = "25f5871d5270ed80f2ee750b95600c8d69b05f8653ad3be913b2ad2e924fefcb" dependencies = [ "gethostname", ] @@ -2692,42 +2591,29 @@ dependencies = [ [[package]] name = "mail-send" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "735ca5a9c5b6acb5f9e7089ee7b96d10c54d4df91e9b47321ef6bb468f90483d" +checksum = "7a575d25cf00ed68e5790b473b29242a47e991c6187785d47b45e31fc5816554" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "gethostname", - "mail-auth", - "mail-builder", - "md5", - "rand", - "rustls 0.22.3", + "rustls 0.23.12", "rustls-pki-types", "smtp-proto", "tokio", - "tokio-rustls 0.25.0", - "webpki-roots 0.26.1", + "tokio-rustls 0.26.0", + "webpki-roots 0.26.3", ] [[package]] -name = "maildirpp" -version = "0.0.2" +name = "maildirs" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739f52fb085592150b1a1ece82ffc4e29e1621b222141e709a64943282f0e6e5" +checksum = "2b7facca4e88a8ab98c16ddd66290d592a6c6f63459e880234a1c6abc8f97491" dependencies = [ "gethostname", - "log", "thiserror", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", + "walkdir", ] [[package]] @@ -2763,9 +2649,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -2799,9 +2685,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -2818,6 +2704,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi", + "windows-sys 0.52.0", +] + [[package]] name = "mirai-annotations" version = "1.12.0" @@ -2826,9 +2724,7 @@ checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" [[package]] name = "mml-lib" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c6ac41c419e7857fdf7104a2f750c0d575969fa32f50a9d370ea3a3bcab1bf" +version = "1.0.13" dependencies = [ "async-recursion", "chumsky", @@ -2873,18 +2769,6 @@ dependencies = [ "memoffset 0.7.1", ] -[[package]] -name = "nix" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" -dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "nom" version = "7.1.3" @@ -2901,30 +2785,17 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "filetime", "inotify", "kqueue", "libc", "log", - "mio", + "mio 0.8.11", "walkdir", "windows-sys 0.48.0", ] -[[package]] -name = "notify-rust" -version = "4.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827c5edfa80235ded4ab3fe8e9dc619b4f866ef16fe9b1c6b8a7f8692c0f2226" -dependencies = [ - "log", - "mac-notification-sys", - "serde", - "tauri-winrt-notification", - "zbus", -] - [[package]] name = "notmuch" version = "0.8.0" @@ -2947,9 +2818,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -2961,11 +2832,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2990,19 +2860,13 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-derive" version = "0.4.2" @@ -3011,7 +2875,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -3025,9 +2889,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -3036,11 +2900,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -3048,24 +2911,14 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -3095,7 +2948,7 @@ dependencies = [ "base64 0.13.1", "chrono", "getrandom", - "http", + "http 0.2.12", "rand", "reqwest", "serde", @@ -3106,35 +2959,6 @@ dependencies = [ "url", ] -[[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 = "object" version = "0.32.2" @@ -3150,12 +2974,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.1.5" @@ -3265,12 +3083,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] @@ -3289,45 +3107,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core", - "subtle", + "windows-targets 0.52.6", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", - "hmac", - "password-hash", - "sha2", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem-rfc7468" @@ -3346,9 +3141,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap", @@ -3360,10 +3155,10 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27e1f8e085bfa9b85763fe3ddaacbe90a09cd847b3833129153a6cb063bbe132" dependencies = [ - "aes 0.8.4", + "aes", "base64 0.21.7", "bitfield", - "block-padding 0.3.3", + "block-padding", "blowfish", "bstr", "buffer-redux", @@ -3372,7 +3167,7 @@ dependencies = [ "cast5", "cfb-mode", "chrono", - "cipher 0.4.4", + "cipher", "crc24", "curve25519-dalek", "derive_builder", @@ -3414,8 +3209,8 @@ checksum = "c6802b1ef0dfc50217185a1eda6ddd546b65ffa8b80f942aa1feda6536adf165" dependencies = [ "async-recursion", "futures", - "hyper", - "hyper-rustls", + "hyper 0.14.30", + "hyper-rustls 0.24.2", "log", "pgp", "rand", @@ -3427,6 +3222,26 @@ dependencies = [ "z-base-32", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -3441,12 +3256,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-io", ] @@ -3477,12 +3292,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "polling" version = "2.8.0" @@ -3501,36 +3310,33 @@ dependencies = [ [[package]] name = "polling" -version = "3.6.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.32", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "prettyplease" @@ -3539,7 +3345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -3587,9 +3393,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.80" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -3612,24 +3418,6 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -[[package]] -name = "quick-xml" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" -dependencies = [ - "memchr", -] - -[[package]] -name = "quick-xml" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" -dependencies = [ - "memchr", -] - [[package]] name = "quote" version = "1.0.36" @@ -3700,11 +3488,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] @@ -3720,14 +3508,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -3752,13 +3540,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -3775,9 +3563,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -3790,11 +3578,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", @@ -3802,7 +3590,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", "serde_json", @@ -3840,21 +3628,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.8" @@ -3865,8 +3638,8 @@ dependencies = [ "cfg-if", "getrandom", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.52.0", ] @@ -3881,9 +3654,9 @@ dependencies = [ [[package]] name = "roff" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" +checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3" [[package]] name = "rsa" @@ -3907,9 +3680,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3942,54 +3715,40 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.8", + "ring", "rustls-webpki 0.101.7", "sct", ] [[package]] name = "rustls" -version = "0.22.3" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-pki-types", - "rustls-webpki 0.102.2", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afabcee0551bd1aa3e18e5adbf2c0544722014b899adb31bd186ec638d3da97e" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "aws-lc-rs", "log", "once_cell", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki 0.102.6", "subtle", "zeroize", ] @@ -4008,12 +3767,12 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "rustls-pki-types", "schannel", "security-framework", @@ -4030,19 +3789,19 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ - "base64 0.22.0", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.4.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" @@ -4050,33 +3809,33 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "aws-lc-rs", - "ring 0.17.8", + "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -4108,8 +3867,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -4128,9 +3887,7 @@ dependencies = [ [[package]] name = "secret-lib" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d99d0df4b8cb27c13c953abaf74bd089922a783fad99cd2b08b369cf7fabcbc9" +version = "0.4.5" dependencies = [ "keyring-lib", "log", @@ -4141,12 +3898,12 @@ dependencies = [ [[package]] name = "secret-service" -version = "3.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da1a5ad4d28c03536f82f77d9f36603f5e37d8869ac98f0a750d5b5686d8d95" +checksum = "b5204d39df37f06d1944935232fd2dfe05008def7ca599bf28c0800366c8a8f9" dependencies = [ - "aes 0.7.5", - "block-modes", + "aes", + "cbc", "futures-util", "generic-array", "hkdf", @@ -4160,11 +3917,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -4173,9 +3930,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -4183,24 +3940,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" dependencies = [ "serde_derive", ] [[package]] name = "serde-toml-merge" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88075e75b01384301454b1c188243552c674263c0c0c3c7ed5dd82291b20798f" +checksum = "93b4e415d6bff989e5e48649ca9b8b4d4997cb069a0c90a84bfd38c7df5e3968" dependencies = [ "toml", ] @@ -4219,22 +3976,23 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -4257,14 +4015,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4362,20 +4120,20 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio", + "mio 0.8.11", "signal-hook", ] [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -4423,9 +4181,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smtp-proto" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34344dcc7dd10b3de9224fd68e5f019fff2246d9cdf8e4322f770f48030e0c83" +checksum = "51b8ad3dd187f0d4debab02ad65405a9919d6a4f7bce25bd64a258781063a53a" [[package]] name = "socket2" @@ -4439,20 +4197,14 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -4495,28 +4247,28 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -4531,9 +4283,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.59" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -4580,41 +4332,23 @@ dependencies = [ "version-compare", ] -[[package]] -name = "tag-generator" -version = "0.1.0" -source = "git+https://github.com/duesee/imap-flow#9ffda2b321247896b3f452072ccfd38789bb547a" -dependencies = [ - "imap-types", - "rand", -] - [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" - -[[package]] -name = "tauri-winrt-notification" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006851c9ccefa3c38a7646b8cec804bb429def3da10497bfa977179869c3e8e2" -dependencies = [ - "quick-xml 0.30.0", - "windows", -] +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand 2.0.2", - "rustix 0.38.32", - "windows-sys 0.52.0", + "fastrand 2.1.0", + "once_cell", + "rustix 0.38.34", + "windows-sys 0.59.0", ] [[package]] @@ -4633,28 +4367,28 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -4667,30 +4401,11 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4703,32 +4418,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", - "mio", - "num_cpus", + "mio 1.0.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.6", + "socket2 0.5.7", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -4737,18 +4451,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" -dependencies = [ - "rustls 0.22.3", - "rustls-pki-types", + "rustls 0.21.12", "tokio", ] @@ -4758,42 +4461,41 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.5", + "rustls 0.23.12", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.12" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -4811,17 +4513,38 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.6", + "winnow 0.6.18", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -4847,7 +4570,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] @@ -4901,9 +4624,9 @@ dependencies = [ [[package]] name = "tree_magic_mini" -version = "3.1.4" +version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ee137597cdb361b55a4746983e4ac1b35ab6024396a419944ad473bb915265" +checksum = "469a727cac55b41448315cc10427c069c618ac59bb6a4480283fcd811749bdc2" dependencies = [ "fnv", "home", @@ -4925,7 +4648,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78e83a30223c757c3947cd144a31014ff04298d8719ae10d03c31c0448c8013" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -4974,15 +4697,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "untrusted" @@ -4992,9 +4709,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna 0.5.0", @@ -5021,9 +4738,9 @@ dependencies = [ [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -5048,15 +4765,15 @@ checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -5104,7 +4821,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -5138,7 +4855,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5167,9 +4884,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" dependencies = [ "rustls-pki-types", ] @@ -5183,7 +4900,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -5210,11 +4927,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -5223,23 +4940,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" -dependencies = [ - "windows-core", - "windows-targets 0.48.5", -] - [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -5257,7 +4964,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -5277,18 +4993,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "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", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5299,9 +5015,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5311,9 +5027,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5323,15 +5039,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5341,9 +5057,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5353,9 +5069,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5365,9 +5081,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5377,9 +5093,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -5392,9 +5108,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.6" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -5442,19 +5158,19 @@ dependencies = [ [[package]] name = "xdg-home" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "xml-rs" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" +checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" [[package]] name = "yansi" @@ -5475,15 +5191,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" dependencies = [ "async-broadcast", - "async-executor", - "async-fs", - "async-io 1.13.0", - "async-lock 2.8.0", "async-process", "async-recursion", - "async-task", "async-trait", - "blocking", "byteorder", "derivative", "enumflags2", @@ -5492,7 +5202,7 @@ dependencies = [ "futures-sink", "futures-util", "hex", - "nix 0.26.4", + "nix", "once_cell", "ordered-stream", "rand", @@ -5537,29 +5247,30 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.72", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5572,56 +5283,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", -] - -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes 0.8.4", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2", - "sha1", - "time", - "zstd", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" -dependencies = [ - "cc", - "pkg-config", + "syn 2.0.72", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cdf9602..16e5d05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "himalaya" description = "CLI to manage emails" -version = "1.0.0-beta.4" +version = "1.0.0" authors = ["soywod "] edition = "2021" license = "MIT" -categories = ["command-line-interface", "command-line-utilities", "email"] -keywords = ["cli", "email", "imap", "smtp", "sync"] +categories = ["command-line-utilities", "email"] +keywords = ["cli", "email", "imap", "maildir", "smtp"] homepage = "https://pimalaya.org/" documentation = "https://pimalaya.org/himalaya/cli/latest/" repository = "https://github.com/soywod/himalaya/" @@ -23,8 +23,9 @@ default = [ "smtp", "sendmail", - "account-discovery", - "account-sync", + "wizard", + # "keyring", + # "oauth2", # "pgp-commands", # "pgp-gpg", @@ -37,8 +38,9 @@ notmuch = ["email-lib/notmuch"] smtp = ["email-lib/smtp"] sendmail = ["email-lib/sendmail"] -account-discovery = ["email-lib/account-discovery"] -account-sync = ["email-lib/account-sync", "maildir"] +keyring = ["email-lib/keyring", "secret-lib?/keyring-tokio"] +oauth2 = ["dep:oauth-lib", "email-lib/oauth2"] +wizard = ["dep:secret-lib", "email-lib/autoconfig"] pgp = [] pgp-commands = ["email-lib/pgp-commands", "mml-lib/pgp-commands", "pgp"] @@ -48,7 +50,7 @@ pgp-native = ["email-lib/pgp-native", "mml-lib/pgp-native", "pgp"] [dependencies] ariadne = "0.2" async-trait = "0.1" -clap = { version = "4.4", features = ["derive", "wrap_help", "env"] } +clap = { version = "4.4", features = ["derive", "env", "wrap_help"] } clap_complete = "4.4" clap_mangen = "0.2" color-eyre = "0.6.3" @@ -56,19 +58,19 @@ comfy-table = "7.1.1" console = "0.15.2" crossterm = "0.27" dirs = "4" -email-lib = { version = "=0.24.1", default-features = false, features = ["derive", "tracing"] } +email-lib = { version = "=0.24.1", default-features = false, features = ["derive", "thread", "tracing"] } email_address = "0.2.4" erased-serde = "0.3" indicatif = "0.17" inquire = "0.7.4" mail-builder = "0.3" md5 = "0.7" -mml-lib = { version = "=1.0.12", default-features = false, features = ["derive"] } -oauth-lib = "=0.1.1" +mml-lib = { version = "=1.0.13", default-features = false, features = ["derive"] } +oauth-lib = { version = "=0.1.1", optional = true } once_cell = "1.16" petgraph = "0.6" process-lib = { version = "=0.4.2", features = ["derive"] } -secret-lib = { version = "=0.4.4", features = ["derive"] } +secret-lib = { version = "=0.4.5", default-features = false, features = ["command", "derive"], optional = true } serde = { version = "1", features = ["derive"] } serde-toml-merge = "0.3" serde_json = "1" @@ -86,8 +88,6 @@ url = "2.2" uuid = { version = "0.8", features = ["v4"] } [patch.crates-io] -# WIP: transition from `imap` to `imap-{types,codec,client}` -email-lib = { git = "https://git.sr.ht/~soywod/pimalaya" } -imap-client = { git = "https://github.com/soywod/imap-client.git" } -imap-codec = { git = "https://github.com/duesee/imap-codec.git" } -imap-types = { git = "https://github.com/duesee/imap-codec.git" } +email-lib = { path = "/home/soywod/sourcehut/pimalaya/email" } +secret-lib = { path = "/home/soywod/sourcehut/pimalaya/secret" } +mml-lib = { path = "/home/soywod/sourcehut/pimalaya/mml" } diff --git a/src/account/command/check_up.rs b/src/account/command/check_up.rs index 8d18332..9693137 100644 --- a/src/account/command/check_up.rs +++ b/src/account/command/check_up.rs @@ -26,11 +26,7 @@ impl AccountCheckUpCommand { printer.log("Checking configuration integrity…")?; - let (toml_account_config, account_config) = config.clone().into_account_configs( - account, - #[cfg(feature = "account-sync")] - true, - )?; + let (toml_account_config, account_config) = config.clone().into_account_configs(account)?; let used_backends = toml_account_config.get_used_backends(); printer.log("Checking backend context integrity…")?; @@ -76,7 +72,7 @@ impl AccountCheckUpCommand { #[cfg(feature = "notmuch")] { - printer.print("Checking Notmuch integrity…")?; + printer.log("Checking Notmuch integrity…")?; let notmuch = ctx_builder .notmuch diff --git a/src/account/command/configure.rs b/src/account/command/configure.rs index cddde83..6a3fb0a 100644 --- a/src/account/command/configure.rs +++ b/src/account/command/configure.rs @@ -42,6 +42,7 @@ impl AccountConfigureCommand { if let Some(ref config) = account_config.imap { let reset = match &config.auth { ImapAuthConfig::Passwd(config) => config.reset().await, + #[cfg(feature = "oauth2")] ImapAuthConfig::OAuth2(config) => config.reset().await, }; if let Err(err) = reset { @@ -54,6 +55,7 @@ impl AccountConfigureCommand { if let Some(ref config) = account_config.smtp { let reset = match &config.auth { SmtpAuthConfig::Passwd(config) => config.reset().await, + #[cfg(feature = "oauth2")] SmtpAuthConfig::OAuth2(config) => config.reset().await, }; if let Err(err) = reset { @@ -74,6 +76,7 @@ impl AccountConfigureCommand { ImapAuthConfig::Passwd(config) => { config.configure(|| prompt::passwd("IMAP password")).await } + #[cfg(feature = "oauth2")] ImapAuthConfig::OAuth2(config) => { config .configure(|| prompt::secret("IMAP OAuth 2.0 client secret")) @@ -88,6 +91,7 @@ impl AccountConfigureCommand { SmtpAuthConfig::Passwd(config) => { config.configure(|| prompt::passwd("SMTP password")).await } + #[cfg(feature = "oauth2")] SmtpAuthConfig::OAuth2(config) => { config .configure(|| prompt::secret("SMTP OAuth 2.0 client secret")) diff --git a/src/account/command/mod.rs b/src/account/command/mod.rs index 5f2de44..81c209c 100644 --- a/src/account/command/mod.rs +++ b/src/account/command/mod.rs @@ -1,16 +1,12 @@ mod check_up; mod configure; mod list; -#[cfg(feature = "account-sync")] -mod sync; -use color_eyre::Result; use clap::Subcommand; +use color_eyre::Result; use crate::{config::TomlConfig, printer::Printer}; -#[cfg(feature = "account-sync")] -use self::sync::AccountSyncCommand; use self::{ check_up::AccountCheckUpCommand, configure::AccountConfigureCommand, list::AccountListCommand, }; @@ -30,10 +26,6 @@ pub enum AccountSubcommand { #[command(alias = "lst")] List(AccountListCommand), - - #[cfg(feature = "account-sync")] - #[command(alias = "synchronize", alias = "synchronise")] - Sync(AccountSyncCommand), } impl AccountSubcommand { @@ -43,8 +35,6 @@ impl AccountSubcommand { Self::CheckUp(cmd) => cmd.execute(printer, config).await, Self::Configure(cmd) => cmd.execute(printer, config).await, Self::List(cmd) => cmd.execute(printer, config).await, - #[cfg(feature = "account-sync")] - Self::Sync(cmd) => cmd.execute(printer, config).await, } } } diff --git a/src/account/command/sync.rs b/src/account/command/sync.rs deleted file mode 100644 index 0950eb2..0000000 --- a/src/account/command/sync.rs +++ /dev/null @@ -1,268 +0,0 @@ -use clap::{ArgAction, Parser}; -use color_eyre::{eyre::bail, eyre::eyre, Result}; -use email::backend::context::BackendContextBuilder; -#[cfg(feature = "imap")] -use email::imap::ImapContextBuilder; -use email::{ - account::sync::AccountSyncBuilder, - backend::BackendBuilder, - folder::sync::config::FolderSyncStrategy, - sync::{hash::SyncHash, SyncEvent}, -}; -use indicatif::{MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; -use once_cell::sync::Lazy; -use std::{ - collections::{BTreeSet, HashMap}, - sync::{Arc, Mutex}, -}; -use tracing::info; - -use crate::{ - account::arg::name::OptionalAccountNameArg, backend::BackendKind, config::TomlConfig, - printer::Printer, -}; - -static MAIN_PROGRESS_STYLE: Lazy = Lazy::new(|| { - ProgressStyle::with_template(" {spinner:.dim} {msg:.dim}\n {wide_bar:.cyan/blue} \n").unwrap() -}); - -static SUB_PROGRESS_STYLE: Lazy = Lazy::new(|| { - ProgressStyle::with_template( - " {prefix:.bold} — {wide_msg:.dim} \n {wide_bar:.black/black} {percent}% ", - ) - .unwrap() -}); - -static SUB_PROGRESS_DONE_STYLE: Lazy = Lazy::new(|| { - ProgressStyle::with_template(" {prefix:.bold} \n {wide_bar:.green} {percent}% ").unwrap() -}); - -/// Synchronize an account. -/// -/// This command allows you to synchronize all folders and emails -/// (including envelopes and messages) of a given account into a local -/// Maildir folder. -#[derive(Debug, Parser)] -pub struct AccountSyncCommand { - #[command(flatten)] - pub account: OptionalAccountNameArg, - - /// Run the synchronization without applying any changes. - /// - /// Instead, a report will be printed to stdout containing all the - /// changes the synchronization plan to do. - #[arg(long, short)] - pub dry_run: bool, - - /// Synchronize only specific folders. - /// - /// Only the given folders will be synchronized (including - /// associated envelopes and messages). Useful when you need to - /// speed up the synchronization process. A good usecase is to - /// synchronize only the INBOX in order to quickly check for new - /// messages. - #[arg(long, short = 'f')] - #[arg(value_name = "FOLDER", action = ArgAction::Append)] - #[arg(conflicts_with = "exclude_folder", conflicts_with = "all_folders")] - pub include_folder: Vec, - - /// Omit specific folders from the synchronization. - /// - /// The given folders will be excluded from the synchronization - /// (including associated envelopes and messages). Useful when you - /// have heavy folders that you do not want to take care of, or to - /// speed up the synchronization process. - #[arg(long, short = 'x')] - #[arg(value_name = "FOLDER", action = ArgAction::Append)] - #[arg(conflicts_with = "include_folder", conflicts_with = "all_folders")] - pub exclude_folder: Vec, - - /// Synchronize all exsting folders. - #[arg(long, short = 'A')] - #[arg(conflicts_with = "include_folder", conflicts_with = "exclude_folder")] - pub all_folders: bool, -} - -impl AccountSyncCommand { - pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { - info!("executing sync account command"); - - let account = self.account.name.as_deref(); - let (toml_account_config, account_config) = - config.clone().into_account_configs(account, true)?; - let account_name = account_config.name.as_str(); - - match toml_account_config.sync_kind() { - Some(BackendKind::Imap) | Some(BackendKind::ImapCache) => { - let imap_config = toml_account_config - .imap - .as_ref() - .map(Clone::clone) - .map(Arc::new) - .ok_or_else(|| eyre!("imap config not found"))?; - let imap_ctx = ImapContextBuilder::new(account_config.clone(), imap_config) - .with_prebuilt_credentials() - .await?; - let imap = BackendBuilder::new(account_config.clone(), imap_ctx); - self.sync(printer, account_name, imap).await - } - Some(backend) => bail!("backend {backend:?} not supported for synchronization"), - None => bail!("no backend configured for synchronization"), - } - } - - async fn sync( - self, - printer: &mut impl Printer, - account_name: &str, - right: BackendBuilder, - ) -> Result<()> { - let included_folders = BTreeSet::from_iter(self.include_folder); - let excluded_folders = BTreeSet::from_iter(self.exclude_folder); - - let folder_filters = if !included_folders.is_empty() { - Some(FolderSyncStrategy::Include(included_folders)) - } else if !excluded_folders.is_empty() { - Some(FolderSyncStrategy::Exclude(excluded_folders)) - } else if self.all_folders { - Some(FolderSyncStrategy::All) - } else { - None - }; - - let sync_builder = - AccountSyncBuilder::try_new(right)?.with_some_folder_filters(folder_filters); - - if self.dry_run { - let report = sync_builder.with_dry_run(true).sync().await?; - let mut hunks_count = report.folder.patch.len(); - - if !report.folder.patch.is_empty() { - printer.log("Folders patch:")?; - for (hunk, _) in report.folder.patch { - printer.log(format!(" - {hunk}"))?; - } - printer.log("")?; - } - - if !report.email.patch.is_empty() { - printer.log("Envelopes patch:")?; - for (hunk, _) in report.email.patch { - hunks_count += 1; - printer.log(format!(" - {hunk}"))?; - } - printer.log("")?; - } - - printer.out(format!( - "Estimated patch length for account {account_name} to be synchronized: {hunks_count}" - ))?; - } else if printer.is_json() { - sync_builder.sync().await?; - printer.out(format!("Account {account_name} successfully synchronized!"))?; - } else { - let multi = MultiProgress::new(); - let sub_progresses = Mutex::new(HashMap::new()); - let main_progress = multi.add( - ProgressBar::new(100) - .with_style(MAIN_PROGRESS_STYLE.clone()) - .with_message("Listing folders…"), - ); - - main_progress.tick(); - - let report = sync_builder - .with_handler(move |evt| { - match evt { - SyncEvent::ListedAllFolders => { - main_progress.set_message("Synchronizing folders…"); - } - SyncEvent::ProcessedAllFolderHunks => { - main_progress.set_message("Listing envelopes…"); - } - SyncEvent::GeneratedEmailPatch(patches) => { - let patches_len = patches.values().flatten().count(); - main_progress.set_length(patches_len as u64); - main_progress.set_position(0); - main_progress.set_message("Synchronizing emails…"); - - let mut envelopes_progresses = sub_progresses.lock().unwrap(); - for (folder, patch) in patches { - let progress = ProgressBar::new(patch.len() as u64) - .with_style(SUB_PROGRESS_STYLE.clone()) - .with_prefix(folder.clone()) - .with_finish(ProgressFinish::AndClear); - let progress = multi.add(progress); - envelopes_progresses.insert(folder, progress.clone()); - } - } - SyncEvent::ProcessedEmailHunk(hunk) => { - main_progress.inc(1); - let mut progresses = sub_progresses.lock().unwrap(); - if let Some(progress) = progresses.get_mut(hunk.folder()) { - progress.inc(1); - if progress.position() == (progress.length().unwrap() - 1) { - progress.set_style(SUB_PROGRESS_DONE_STYLE.clone()) - } else { - progress.set_message(format!("{hunk}…")); - } - } - } - SyncEvent::ProcessedAllEmailHunks => { - let mut progresses = sub_progresses.lock().unwrap(); - for progress in progresses.values() { - progress.finish_and_clear() - } - progresses.clear(); - - main_progress.set_length(100); - main_progress.set_position(100); - main_progress.set_message("Expunging folders…"); - } - SyncEvent::ExpungedAllFolders => { - main_progress.finish_and_clear(); - } - _ => { - main_progress.tick(); - } - }; - - async { Ok(()) } - }) - .sync() - .await?; - - let folders_patch_err = report - .folder - .patch - .iter() - .filter_map(|(hunk, err)| err.as_ref().map(|err| (hunk, err))) - .collect::>(); - if !folders_patch_err.is_empty() { - printer.log("")?; - printer.log("Errors occurred while applying the folders patch:")?; - folders_patch_err - .iter() - .try_for_each(|(hunk, err)| printer.log(format!(" - {hunk}: {err}")))?; - } - - let envelopes_patch_err = report - .email - .patch - .iter() - .filter_map(|(hunk, err)| err.as_ref().map(|err| (hunk, err))) - .collect::>(); - if !envelopes_patch_err.is_empty() { - printer.log("")?; - printer.log("Errors occurred while applying the envelopes patch:")?; - for (hunk, err) in envelopes_patch_err { - printer.log(format!(" - {hunk}: {err}"))?; - } - } - - printer.out(format!("Account {account_name} successfully synchronized!"))?; - } - - Ok(()) - } -} diff --git a/src/account/config.rs b/src/account/config.rs index 23abca7..b64c7b0 100644 --- a/src/account/config.rs +++ b/src/account/config.rs @@ -24,25 +24,6 @@ use crate::{ folder::config::FolderConfig, message::config::MessageConfig, }; -#[cfg(feature = "account-sync")] -#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] -#[serde(rename_all = "kebab-case", deny_unknown_fields)] -pub struct SyncConfig { - pub backend: Option, - pub enable: Option, - pub dir: Option, -} - -impl From for email::account::sync::config::SyncConfig { - fn from(config: SyncConfig) -> Self { - Self { - enable: config.enable, - dir: config.dir, - ..Default::default() - } - } -} - /// Represents all existing kind of account config. #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] @@ -55,8 +36,6 @@ pub struct TomlAccountConfig { pub downloads_dir: Option, pub backend: Option, - #[cfg(feature = "account-sync")] - pub sync: Option, #[cfg(feature = "pgp")] pub pgp: Option, @@ -79,13 +58,6 @@ pub struct TomlAccountConfig { } impl TomlAccountConfig { - pub fn sync_kind(&self) -> Option<&BackendKind> { - self.sync - .as_ref() - .and_then(|sync| sync.backend.as_ref()) - .or(self.backend.as_ref()) - } - pub fn add_folder_kind(&self) -> Option<&BackendKind> { self.folder .as_ref() @@ -150,14 +122,6 @@ impl TomlAccountConfig { .or(self.backend.as_ref()) } - pub fn watch_envelopes_kind(&self) -> Option<&BackendKind> { - self.envelope - .as_ref() - .and_then(|envelope| envelope.watch.as_ref()) - .and_then(|watch| watch.backend.as_ref()) - .or(self.backend.as_ref()) - } - pub fn add_flags_kind(&self) -> Option<&BackendKind> { self.flag .as_ref() diff --git a/src/account/mod.rs b/src/account/mod.rs index 1cf6e9a..c9dac47 100644 --- a/src/account/mod.rs +++ b/src/account/mod.rs @@ -1,6 +1,7 @@ pub mod arg; pub mod command; pub mod config; +#[cfg(feature = "wizard")] pub(crate) mod wizard; use comfy_table::{presets, Attribute, Cell, Color, ContentArrangement, Row, Table}; diff --git a/src/account/wizard.rs b/src/account/wizard.rs index 296560a..1562643 100644 --- a/src/account/wizard.rs +++ b/src/account/wizard.rs @@ -1,12 +1,8 @@ -#[cfg(feature = "account-sync")] -use crate::account::config::SyncConfig; use color_eyre::{eyre::OptionExt, Result}; -#[cfg(feature = "account-sync")] use email_address::EmailAddress; use inquire::validator::{ErrorMessage, Validation}; use std::{path::PathBuf, str::FromStr}; -#[cfg(feature = "account-discovery")] use crate::wizard_warn; use crate::{ backend::{self, config::BackendConfig, BackendKind}, @@ -34,14 +30,11 @@ pub(crate) async fn configure() -> Result> { let addr = EmailAddress::from_str(&config.email).unwrap(); - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] let autoconfig_email = config.email.to_owned(); - #[cfg(feature = "account-discovery")] - let autoconfig = tokio::spawn(async move { - email::account::discover::from_addr(&autoconfig_email) - .await - .ok() - }); + #[cfg(feature = "wizard")] + let autoconfig = + tokio::spawn(async move { email::autoconfig::from_addr(&autoconfig_email).await.ok() }); let account_name = inquire::Text::new("Account name: ") .with_default( @@ -65,12 +58,12 @@ pub(crate) async fn configure() -> Result> { )); let email = &config.email; - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] let autoconfig = autoconfig.await?; - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] let autoconfig = autoconfig.as_ref(); - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] if let Some(config) = autoconfig { if config.is_gmail() { println!(); @@ -83,7 +76,7 @@ pub(crate) async fn configure() -> Result> { match backend::wizard::configure( &account_name, email, - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] autoconfig, ) .await? @@ -109,7 +102,7 @@ pub(crate) async fn configure() -> Result> { match backend::wizard::configure_sender( &account_name, email, - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] autoconfig, ) .await? @@ -139,21 +132,5 @@ pub(crate) async fn configure() -> Result> { _ => (), }; - #[cfg(feature = "account-sync")] - { - let should_configure_sync = - inquire::Confirm::new("Do you need offline access for your account?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); - - if should_configure_sync { - config.sync = Some(SyncConfig { - enable: Some(true), - ..Default::default() - }); - } - } - Ok(Some((account_name, config))) } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 9fe88c4..d7a9112 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,9 +1,12 @@ pub mod config; + +#[cfg(feature = "wizard")] pub(crate) mod wizard; use async_trait::async_trait; use color_eyre::Result; use std::{fmt::Display, ops::Deref, sync::Arc}; +use tracing::instrument; #[cfg(feature = "imap")] use email::imap::{ImapContextBuilder, ImapContextSync}; @@ -24,7 +27,6 @@ use email::{ get::GetEnvelope, list::{ListEnvelopes, ListEnvelopesOptions}, thread::ThreadEnvelopes, - watch::WatchEnvelopes, Id, SingleId, }, flag::{add::AddFlags, remove::RemoveFlags, set::SetFlags, Flag, Flags}, @@ -59,8 +61,6 @@ pub enum BackendKind { #[cfg(feature = "imap")] Imap, - #[cfg(all(feature = "imap", feature = "account-sync"))] - ImapCache, #[cfg(feature = "maildir")] Maildir, @@ -85,8 +85,6 @@ impl Display for BackendKind { #[cfg(feature = "imap")] Self::Imap => "IMAP", - #[cfg(all(feature = "imap", feature = "account-sync"))] - Self::ImapCache => "IMAP cache", #[cfg(feature = "maildir")] Self::Maildir => "Maildir", @@ -112,9 +110,6 @@ pub struct BackendContextBuilder { #[cfg(feature = "imap")] pub imap: Option, - #[cfg(all(feature = "imap", feature = "account-sync"))] - pub imap_cache: Option, - #[cfg(feature = "maildir")] pub maildir: Option, @@ -156,26 +151,6 @@ impl BackendContextBuilder { } }, - #[cfg(all(feature = "imap", feature = "account-sync"))] - imap_cache: { - let builder = toml_account_config - .imap - .as_ref() - .filter(|_| kinds.contains(&&BackendKind::ImapCache)) - .map(Clone::clone) - .map(Arc::new) - .map(|imap_config| { - email::backend::context::BackendContextBuilder::try_to_sync_cache_builder( - &ImapContextBuilder::new(account_config.clone(), imap_config), - &account_config, - ) - }); - match builder { - Some(builder) => Some(builder?), - None => None, - } - }, - #[cfg(feature = "maildir")] maildir: toml_account_config .maildir @@ -227,11 +202,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.add_folder_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.add_folder_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.add_folder()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.add_folder_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -244,11 +214,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.list_folders_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.list_folders_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.list_folders()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.list_folders_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -261,11 +226,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.expunge_folder_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.expunge_folder_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.expunge_folder()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.expunge_folder_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -278,11 +238,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.purge_folder_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.purge_folder_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.purge_folder()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.purge_folder_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -295,11 +250,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.delete_folder_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.delete_folder_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.delete_folder()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.delete_folder_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -312,11 +262,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.get_envelope_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.get_envelope_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.get_envelope()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.get_envelope_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -329,11 +274,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.list_envelopes_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.list_envelopes_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.list_envelopes()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.list_envelopes_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -346,11 +286,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.thread_envelopes_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.thread_envelopes_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.thread_envelopes()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.thread_envelopes_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -359,32 +294,10 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { } } - fn watch_envelopes(&self) -> Option> { - match self.toml_account_config.watch_envelopes_kind() { - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => self.watch_envelopes_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.watch_envelopes()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } - #[cfg(feature = "maildir")] - Some(BackendKind::Maildir) => self.watch_envelopes_with_some(&self.maildir), - #[cfg(feature = "notmuch")] - Some(BackendKind::Notmuch) => self.watch_envelopes_with_some(&self.notmuch), - _ => None, - } - } - fn add_flags(&self) -> Option> { match self.toml_account_config.add_flags_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.add_flags_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.add_flags()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.add_flags_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -397,11 +310,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.set_flags_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.set_flags_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.set_flags()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.set_flags_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -414,11 +322,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.remove_flags_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.remove_flags_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.remove_flags()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.remove_flags_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -431,11 +334,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.add_message_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.add_message_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.add_message()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.add_message_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -458,11 +356,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.peek_messages_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.peek_messages_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.peek_messages()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.peek_messages_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -475,11 +368,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.get_messages_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.get_messages_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.get_messages()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.get_messages_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -492,11 +380,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.copy_messages_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.copy_messages_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.copy_messages()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.copy_messages_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -509,11 +392,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.move_messages_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.move_messages_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.move_messages()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.move_messages_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -526,11 +404,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { match self.toml_account_config.delete_messages_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => self.delete_messages_with_some(&self.imap), - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - let f = self.imap_cache.as_ref()?.delete_messages()?; - Some(Arc::new(move |ctx| f(ctx.imap_cache.as_ref()?))) - } #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => self.delete_messages_with_some(&self.maildir), #[cfg(feature = "notmuch")] @@ -547,11 +420,6 @@ impl email::backend::context::BackendContextBuilder for BackendContextBuilder { ctx.imap = Some(imap.build().await?); } - #[cfg(all(feature = "imap", feature = "account-sync"))] - if let Some(maildir) = self.imap_cache { - ctx.imap_cache = Some(maildir.build().await?); - } - #[cfg(feature = "maildir")] if let Some(maildir) = self.maildir { ctx.maildir = Some(maildir.build().await?); @@ -581,9 +449,6 @@ pub struct BackendContext { #[cfg(feature = "imap")] pub imap: Option, - #[cfg(all(feature = "imap", feature = "account-sync"))] - pub imap_cache: Option, - #[cfg(feature = "maildir")] pub maildir: Option, @@ -663,37 +528,28 @@ impl Backend { }) } + #[instrument(skip(self))] fn build_id_mapper( &self, folder: &str, backend_kind: Option<&BackendKind>, ) -> Result { #[allow(unused_mut)] - let mut id_mapper = IdMapper::Dummy; - - match backend_kind { - #[cfg(feature = "maildir")] - Some(BackendKind::Maildir) => { - if let Some(_) = &self.toml_account_config.maildir { - id_mapper = IdMapper::new(&self.backend.account_config, folder)?; - } + #[cfg(feature = "maildir")] + if let Some(BackendKind::Maildir) = backend_kind { + if let Some(_) = &self.toml_account_config.maildir { + return Ok(IdMapper::new(&self.backend.account_config, folder)?); } + } - #[cfg(all(feature = "imap", feature = "account-sync"))] - Some(BackendKind::ImapCache) => { - id_mapper = IdMapper::new(&self.backend.account_config, folder)?; + #[cfg(feature = "notmuch")] + if let Some(BackendKind::Notmuch) = backend_kind { + if let Some(_) = &self.toml_account_config.notmuch { + return Ok(IdMapper::new(&self.backend.account_config, folder)?); } + } - #[cfg(feature = "notmuch")] - Some(BackendKind::Notmuch) => { - if let Some(_) = &self.toml_account_config.notmuch { - id_mapper = IdMapper::new(&self.backend.account_config, folder)?; - } - } - _ => (), - }; - - Ok(id_mapper) + Ok(IdMapper::Dummy) } pub async fn list_envelopes( @@ -868,11 +724,6 @@ impl Backend { self.backend.send_message_then_save_copy(msg).await?; Ok(()) } - - pub async fn watch_envelopes(&self, folder: &str) -> Result<()> { - self.backend.watch_envelopes(folder).await?; - Ok(()) - } } impl Deref for Backend { diff --git a/src/backend/wizard.rs b/src/backend/wizard.rs index b24dca1..35285ec 100644 --- a/src/backend/wizard.rs +++ b/src/backend/wizard.rs @@ -1,6 +1,5 @@ use color_eyre::Result; -#[cfg(feature = "account-discovery")] -use email::account::discover::config::AutoConfig; +use email::autoconfig::config::AutoConfig; use inquire::Select; #[cfg(feature = "imap")] @@ -35,7 +34,7 @@ const SEND_MESSAGE_BACKEND_KINDS: &[BackendKind] = &[ pub(crate) async fn configure( account_name: &str, email: &str, - #[cfg(feature = "account-discovery")] autoconfig: Option<&AutoConfig>, + autoconfig: Option<&AutoConfig>, ) -> Result> { let kind = Select::new("Default email backend", DEFAULT_BACKEND_KINDS.to_vec()) .with_starting_cursor(0) @@ -47,7 +46,7 @@ pub(crate) async fn configure( imap::wizard::configure( account_name, email, - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] autoconfig, ) .await?, @@ -65,7 +64,7 @@ pub(crate) async fn configure( pub(crate) async fn configure_sender( account_name: &str, email: &str, - #[cfg(feature = "account-discovery")] autoconfig: Option<&AutoConfig>, + autoconfig: Option<&AutoConfig>, ) -> Result> { let kind = Select::new( "Backend for sending messages", @@ -80,7 +79,7 @@ pub(crate) async fn configure_sender( smtp::wizard::configure( account_name, email, - #[cfg(feature = "account-discovery")] + #[cfg(feature = "wizard")] autoconfig, ) .await?, diff --git a/src/config/mod.rs b/src/config/mod.rs index fe0474a..043db8b 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "wizard")] pub mod wizard; use color_eyre::{ @@ -7,7 +8,7 @@ use color_eyre::{ use dirs::{config_dir, home_dir}; use email::{ account::config::AccountConfig, config::Config, envelope::config::EnvelopeConfig, - flag::config::FlagConfig, folder::config::FolderConfig, message::config::MessageConfig, + folder::config::FolderConfig, message::config::MessageConfig, }; use serde::{Deserialize, Serialize}; use serde_toml_merge::merge; @@ -16,9 +17,9 @@ use std::{collections::HashMap, fs, path::PathBuf, sync::Arc}; use toml::{self, Value}; use tracing::debug; -#[cfg(feature = "account-sync")] -use crate::backend::BackendKind; -use crate::{account::config::TomlAccountConfig, wizard_warn}; +use crate::account::config::TomlAccountConfig; +#[cfg(feature = "wizard")] +use crate::wizard_warn; /// Represents the user config file. #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] @@ -84,9 +85,8 @@ impl TomlConfig { /// program stops. /// /// NOTE: the wizard can only be used with interactive shells. + #[cfg(feature = "wizard")] async fn from_wizard(path: &PathBuf) -> Result { - use std::process; - wizard_warn!("Cannot find existing configuration at {path:?}."); let confirm = inquire::Confirm::new("Would you like to create one with the wizard? ") @@ -95,10 +95,15 @@ impl TomlConfig { .unwrap_or_default(); if !confirm { - process::exit(0); + std::process::exit(0); } - wizard::configure(path).await + return wizard::configure(path).await; + } + + #[cfg(not(feature = "wizard"))] + async fn from_wizard(path: &PathBuf) -> Result { + bail!("Cannot find existing configuration at {path:?}."); } /// Read and parse the TOML configuration from default paths. @@ -182,14 +187,14 @@ impl TomlConfig { .ok_or_else(|| eyre!("cannot find account {name}")), }?; - #[cfg(feature = "imap")] + #[cfg(all(feature = "imap", feature = "keyring"))] if let Some(imap_config) = toml_account_config.imap.as_mut() { imap_config .auth .replace_undefined_keyring_entries(&account_name)?; } - #[cfg(feature = "smtp")] + #[cfg(all(feature = "smtp", feature = "keyring"))] if let Some(smtp_config) = toml_account_config.smtp.as_mut() { smtp_config .auth @@ -203,21 +208,8 @@ impl TomlConfig { pub fn into_account_configs( self, account_name: Option<&str>, - #[cfg(feature = "account-sync")] disable_cache: bool, ) -> Result<(Arc, Arc)> { - #[cfg_attr(not(feature = "account-sync"), allow(unused_mut))] - let (account_name, mut toml_account_config) = - self.into_toml_account_config(account_name)?; - - #[cfg(feature = "account-sync")] - if let Some(true) = toml_account_config.sync.as_ref().and_then(|c| c.enable) { - if !disable_cache { - toml_account_config.backend = match toml_account_config.backend { - Some(BackendKind::Imap) => Some(BackendKind::ImapCache), - backend => backend, - } - } - } + let (account_name, toml_account_config) = self.into_toml_account_config(account_name)?; let config = Config { display_name: self.display_name, @@ -239,31 +231,19 @@ impl TomlConfig { folder: config.folder.map(|c| FolderConfig { aliases: c.alias, list: c.list.map(|c| c.remote), - #[cfg(feature = "account-sync")] - sync: c.sync, }), envelope: config.envelope.map(|c| EnvelopeConfig { list: c.list.map(|c| c.remote), thread: c.thread.map(|c| c.remote), - watch: c.watch.map(|c| c.remote), - #[cfg(feature = "account-sync")] - sync: c.sync, - }), - flag: config.flag.map(|c| FlagConfig { - #[cfg(feature = "account-sync")] - sync: c.sync, }), + flag: None, message: config.message.map(|c| MessageConfig { read: c.read.map(|c| c.remote), write: c.write.map(|c| c.remote), send: c.send.map(|c| c.remote), delete: c.delete.map(Into::into), - #[cfg(feature = "account-sync")] - sync: c.sync, }), template: config.template, - #[cfg(feature = "account-sync")] - sync: config.sync.map(Into::into), #[cfg(feature = "pgp")] pgp: config.pgp, }, diff --git a/src/config/wizard.rs b/src/config/wizard.rs index bcc8f4f..3a9071f 100644 --- a/src/config/wizard.rs +++ b/src/config/wizard.rs @@ -152,9 +152,6 @@ fn pretty_serialize(config: &TomlConfig) -> Result { #[cfg(feature = "sendmail")] set_table_dotted(item, "sendmail"); - #[cfg(feature = "account-sync")] - set_table_dotted(item, "sync"); - #[cfg(feature = "pgp")] set_table_dotted(item, "pgp"); }) @@ -214,68 +211,6 @@ fn set_tables_dotted<'a>(item: &'a mut Item, keys: impl IntoIterator, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, @@ -130,8 +124,6 @@ impl Default for ListEnvelopesCommand { folder: Default::default(), page: 1, page_size: Default::default(), - #[cfg(feature = "account-sync")] - cache: Default::default(), account: Default::default(), query: Default::default(), table_max_width: Default::default(), @@ -143,11 +135,9 @@ impl ListEnvelopesCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing list envelopes command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let folder = &self.folder.name; let page = 1.max(self.page) - 1; diff --git a/src/email/envelope/command/mod.rs b/src/email/envelope/command/mod.rs index 975effc..7e7cebb 100644 --- a/src/email/envelope/command/mod.rs +++ b/src/email/envelope/command/mod.rs @@ -1,15 +1,12 @@ pub mod list; pub mod thread; -pub mod watch; use clap::Subcommand; use color_eyre::Result; use crate::{config::TomlConfig, printer::Printer}; -use self::{ - list::ListEnvelopesCommand, thread::ThreadEnvelopesCommand, watch::WatchEnvelopesCommand, -}; +use self::{list::ListEnvelopesCommand, thread::ThreadEnvelopesCommand}; /// Manage envelopes. /// @@ -24,9 +21,6 @@ pub enum EnvelopeSubcommand { #[command()] Thread(ThreadEnvelopesCommand), - - #[command()] - Watch(WatchEnvelopesCommand), } impl EnvelopeSubcommand { @@ -35,7 +29,6 @@ impl EnvelopeSubcommand { match self { Self::List(cmd) => cmd.execute(printer, config).await, Self::Thread(cmd) => cmd.execute(printer, config).await, - Self::Watch(cmd) => cmd.execute(printer, config).await, } } } diff --git a/src/email/envelope/command/thread.rs b/src/email/envelope/command/thread.rs index 387bd60..a4754d2 100644 --- a/src/email/envelope/command/thread.rs +++ b/src/email/envelope/command/thread.rs @@ -8,8 +8,6 @@ use email::{ use std::process::exit; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, envelope::EnvelopesTree, folder::arg::name::FolderNameOptionalFlag, printer::Printer, @@ -24,10 +22,6 @@ pub struct ThreadEnvelopesCommand { #[command(flatten)] pub folder: FolderNameOptionalFlag, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, @@ -43,11 +37,9 @@ impl ThreadEnvelopesCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing thread envelopes command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let folder = &self.folder.name; let thread_envelopes_kind = toml_account_config.thread_envelopes_kind(); diff --git a/src/email/envelope/command/watch.rs b/src/email/envelope/command/watch.rs deleted file mode 100644 index f4cc656..0000000 --- a/src/email/envelope/command/watch.rs +++ /dev/null @@ -1,57 +0,0 @@ -use clap::Parser; -use color_eyre::Result; -use email::backend::feature::BackendFeatureSource; -use tracing::info; - -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; -use crate::{ - account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, - folder::arg::name::FolderNameOptionalFlag, printer::Printer, -}; - -/// Watch envelopes for changes. -/// -/// This command allows you to watch a folder and execute hooks when -/// changes occur on envelopes. -#[derive(Debug, Parser)] -pub struct WatchEnvelopesCommand { - #[command(flatten)] - pub folder: FolderNameOptionalFlag, - - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - - #[command(flatten)] - pub account: AccountNameFlag, -} - -impl WatchEnvelopesCommand { - pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { - info!("executing watch envelopes command"); - - let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; - - let watch_envelopes_kind = toml_account_config.watch_envelopes_kind(); - - let backend = Backend::new( - toml_account_config.clone(), - account_config, - watch_envelopes_kind, - |builder| builder.set_watch_envelopes(BackendFeatureSource::Context), - ) - .await?; - - printer.out(format!( - "Start watching folder {folder} for envelopes changes…" - ))?; - - backend.watch_envelopes(folder).await - } -} diff --git a/src/email/envelope/config.rs b/src/email/envelope/config.rs index 4b5e53b..3fda1ea 100644 --- a/src/email/envelope/config.rs +++ b/src/email/envelope/config.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "account-sync")] -use email::envelope::sync::config::EnvelopeSyncConfig; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -9,10 +7,7 @@ use crate::backend::BackendKind; pub struct EnvelopeConfig { pub list: Option, pub thread: Option, - pub watch: Option, pub get: Option, - #[cfg(feature = "account-sync")] - pub sync: Option, } impl EnvelopeConfig { @@ -23,10 +18,6 @@ impl EnvelopeConfig { kinds.extend(list.get_used_backends()); } - if let Some(watch) = &self.watch { - kinds.extend(watch.get_used_backends()); - } - if let Some(get) = &self.get { kinds.extend(get.get_used_backends()); } @@ -75,26 +66,6 @@ impl ThreadEnvelopesConfig { } } -#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] -pub struct WatchEnvelopesConfig { - pub backend: Option, - - #[serde(flatten)] - pub remote: email::envelope::watch::config::WatchEnvelopeConfig, -} - -impl WatchEnvelopesConfig { - pub fn get_used_backends(&self) -> HashSet<&BackendKind> { - let mut kinds = HashSet::default(); - - if let Some(kind) = &self.backend { - kinds.insert(kind); - } - - kinds - } -} - #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct GetEnvelopeConfig { pub backend: Option, diff --git a/src/email/envelope/flag/command/add.rs b/src/email/envelope/flag/command/add.rs index ed7da11..a78c8c9 100644 --- a/src/email/envelope/flag/command/add.rs +++ b/src/email/envelope/flag/command/add.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -26,10 +24,6 @@ pub struct FlagAddCommand { #[command(flatten)] pub args: IdsAndFlagsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -40,11 +34,9 @@ impl FlagAddCommand { let folder = &self.folder.name; let (ids, flags) = into_tuple(&self.args.ids_and_flags); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_flags_kind = toml_account_config.add_flags_kind(); diff --git a/src/email/envelope/flag/command/remove.rs b/src/email/envelope/flag/command/remove.rs index 6e8fc2a..d2e0f6e 100644 --- a/src/email/envelope/flag/command/remove.rs +++ b/src/email/envelope/flag/command/remove.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -26,10 +24,6 @@ pub struct FlagRemoveCommand { #[command(flatten)] pub args: IdsAndFlagsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -40,11 +34,9 @@ impl FlagRemoveCommand { let folder = &self.folder.name; let (ids, flags) = into_tuple(&self.args.ids_and_flags); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let remove_flags_kind = toml_account_config.remove_flags_kind(); diff --git a/src/email/envelope/flag/command/set.rs b/src/email/envelope/flag/command/set.rs index 7913e35..6f4a294 100644 --- a/src/email/envelope/flag/command/set.rs +++ b/src/email/envelope/flag/command/set.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -26,10 +24,6 @@ pub struct FlagSetCommand { #[command(flatten)] pub args: IdsAndFlagsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -40,11 +34,9 @@ impl FlagSetCommand { let folder = &self.folder.name; let (ids, flags) = into_tuple(&self.args.ids_and_flags); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let set_flags_kind = toml_account_config.set_flags_kind(); diff --git a/src/email/envelope/flag/config.rs b/src/email/envelope/flag/config.rs index f7e1a7c..eb75af4 100644 --- a/src/email/envelope/flag/config.rs +++ b/src/email/envelope/flag/config.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "account-sync")] -use email::flag::sync::config::FlagSyncConfig; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -10,8 +8,6 @@ pub struct FlagConfig { pub add: Option, pub set: Option, pub remove: Option, - #[cfg(feature = "account-sync")] - pub sync: Option, } impl FlagConfig { diff --git a/src/email/message/attachment/command/download.rs b/src/email/message/attachment/command/download.rs index 1187717..49ce543 100644 --- a/src/email/message/attachment/command/download.rs +++ b/src/email/message/attachment/command/download.rs @@ -5,8 +5,6 @@ use std::{fs, path::PathBuf}; use tracing::info; use uuid::Uuid; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag, @@ -25,10 +23,6 @@ pub struct AttachmentDownloadCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -40,11 +34,9 @@ impl AttachmentDownloadCommand { let folder = &self.folder.name; let ids = &self.envelopes.ids; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let get_messages_kind = toml_account_config.get_messages_kind(); diff --git a/src/email/message/command/copy.rs b/src/email/message/command/copy.rs index d57f553..a9e408b 100644 --- a/src/email/message/command/copy.rs +++ b/src/email/message/command/copy.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -26,10 +24,6 @@ pub struct MessageCopyCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -42,11 +36,9 @@ impl MessageCopyCommand { let target = &self.target_folder.name; let ids = &self.envelopes.ids; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let copy_messages_kind = toml_account_config.copy_messages_kind(); diff --git a/src/email/message/command/delete.rs b/src/email/message/command/delete.rs index 28b8d6f..c5daad3 100644 --- a/src/email/message/command/delete.rs +++ b/src/email/message/command/delete.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag, @@ -25,10 +23,6 @@ pub struct MessageDeleteCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -40,11 +34,9 @@ impl MessageDeleteCommand { let folder = &self.folder.name; let ids = &self.envelopes.ids; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let delete_messages_kind = toml_account_config.delete_messages_kind(); diff --git a/src/email/message/command/forward.rs b/src/email/message/command/forward.rs index f64c230..a257e64 100644 --- a/src/email/message/command/forward.rs +++ b/src/email/message/command/forward.rs @@ -3,8 +3,6 @@ use color_eyre::{eyre::eyre, Result}; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -36,10 +34,6 @@ pub struct MessageForwardCommand { #[command(flatten)] pub body: MessageRawBodyArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -50,11 +44,9 @@ impl MessageForwardCommand { let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_message_kind = toml_account_config.add_message_kind(); let send_message_kind = toml_account_config.send_message_kind(); diff --git a/src/email/message/command/mailto.rs b/src/email/message/command/mailto.rs index 540aa2f..054975f 100644 --- a/src/email/message/command/mailto.rs +++ b/src/email/message/command/mailto.rs @@ -5,8 +5,6 @@ use mail_builder::MessageBuilder; use tracing::info; use url::Url; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, printer::Printer, ui::editor, @@ -24,10 +22,6 @@ pub struct MessageMailtoCommand { #[arg()] pub url: Url, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -36,8 +30,6 @@ impl MessageMailtoCommand { pub fn new(url: &str) -> Result { Ok(Self { url: Url::parse(url)?, - #[cfg(feature = "account-sync")] - cache: Default::default(), account: Default::default(), }) } @@ -45,11 +37,9 @@ impl MessageMailtoCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing mailto message command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_message_kind = toml_account_config.add_message_kind(); let send_message_kind = toml_account_config.send_message_kind(); diff --git a/src/email/message/command/move.rs b/src/email/message/command/move.rs index c5f4772..0bf8405 100644 --- a/src/email/message/command/move.rs +++ b/src/email/message/command/move.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; #[allow(unused)] use crate::{ account::arg::name::AccountNameFlag, @@ -27,10 +25,6 @@ pub struct MessageMoveCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -43,11 +37,9 @@ impl MessageMoveCommand { let target = &self.target_folder.name; let ids = &self.envelopes.ids; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let move_messages_kind = toml_account_config.move_messages_kind(); diff --git a/src/email/message/command/read.rs b/src/email/message/command/read.rs index edbc5a5..d510c89 100644 --- a/src/email/message/command/read.rs +++ b/src/email/message/command/read.rs @@ -4,8 +4,6 @@ use email::backend::feature::BackendFeatureSource; use mml::message::FilterParts; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; #[allow(unused)] use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, @@ -70,10 +68,6 @@ pub struct MessageReadCommand { #[arg(conflicts_with = "no_headers")] pub headers: Vec, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -85,11 +79,9 @@ impl MessageReadCommand { let folder = &self.folder.name; let ids = &self.envelopes.ids; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let get_messages_kind = toml_account_config.get_messages_kind(); diff --git a/src/email/message/command/reply.rs b/src/email/message/command/reply.rs index a9c1cc1..add6500 100644 --- a/src/email/message/command/reply.rs +++ b/src/email/message/command/reply.rs @@ -3,8 +3,6 @@ use color_eyre::{eyre::eyre, Result}; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -39,10 +37,6 @@ pub struct MessageReplyCommand { #[command(flatten)] pub body: MessageRawBodyArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -52,11 +46,9 @@ impl MessageReplyCommand { info!("executing reply message command"); let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_message_kind = toml_account_config.add_message_kind(); let send_message_kind = toml_account_config.send_message_kind(); diff --git a/src/email/message/command/save.rs b/src/email/message/command/save.rs index 4d00af2..09ff990 100644 --- a/src/email/message/command/save.rs +++ b/src/email/message/command/save.rs @@ -4,8 +4,6 @@ use email::backend::feature::BackendFeatureSource; use std::io::{self, BufRead, IsTerminal}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; #[allow(unused)] use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, @@ -23,10 +21,6 @@ pub struct MessageSaveCommand { #[command(flatten)] pub message: MessageRawArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -37,11 +31,9 @@ impl MessageSaveCommand { let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_message_kind = toml_account_config.add_message_kind(); diff --git a/src/email/message/command/send.rs b/src/email/message/command/send.rs index 6ef0ea3..31a401d 100644 --- a/src/email/message/command/send.rs +++ b/src/email/message/command/send.rs @@ -4,8 +4,6 @@ use email::backend::feature::BackendFeatureSource; use std::io::{self, BufRead, IsTerminal}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, message::arg::MessageRawArg, printer::Printer, @@ -20,10 +18,6 @@ pub struct MessageSendCommand { #[command(flatten)] pub message: MessageRawArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -32,11 +26,9 @@ impl MessageSendCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing send message command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let send_message_kind = toml_account_config.send_message_kind().into_iter().chain( toml_account_config diff --git a/src/email/message/command/thread.rs b/src/email/message/command/thread.rs index 7ba430f..afeb9c7 100644 --- a/src/email/message/command/thread.rs +++ b/src/email/message/command/thread.rs @@ -4,8 +4,6 @@ use email::backend::feature::BackendFeatureSource; use mml::message::FilterParts; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::envelope::arg::ids::EnvelopeIdArg; #[allow(unused)] use crate::{ @@ -71,10 +69,6 @@ pub struct MessageThreadCommand { #[arg(conflicts_with = "no_headers")] pub headers: Vec, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -86,11 +80,9 @@ impl MessageThreadCommand { let folder = &self.folder.name; let id = &self.envelope.id; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let get_messages_kind = toml_account_config.get_messages_kind(); diff --git a/src/email/message/command/write.rs b/src/email/message/command/write.rs index 519431c..423d77b 100644 --- a/src/email/message/command/write.rs +++ b/src/email/message/command/write.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::{backend::feature::BackendFeatureSource, message::Message}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -28,10 +26,6 @@ pub struct MessageWriteCommand { #[command(flatten)] pub body: MessageRawBodyArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -40,11 +34,9 @@ impl MessageWriteCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing write message command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_message_kind = toml_account_config.add_message_kind(); let send_message_kind = toml_account_config.send_message_kind(); diff --git a/src/email/message/config.rs b/src/email/message/config.rs index aa72127..3ac987c 100644 --- a/src/email/message/config.rs +++ b/src/email/message/config.rs @@ -1,6 +1,4 @@ use email::message::delete::config::DeleteMessageStyle; -#[cfg(feature = "account-sync")] -use email::message::sync::config::MessageSyncConfig; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -15,8 +13,6 @@ pub struct MessageConfig { pub copy: Option, pub r#move: Option, pub delete: Option, - #[cfg(feature = "account-sync")] - pub sync: Option, } impl MessageConfig { diff --git a/src/email/message/template/command/forward.rs b/src/email/message/template/command/forward.rs index 4d6495f..3fcde8f 100644 --- a/src/email/message/template/command/forward.rs +++ b/src/email/message/template/command/forward.rs @@ -3,8 +3,6 @@ use color_eyre::{eyre::eyre, Result}; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -34,10 +32,6 @@ pub struct TemplateForwardCommand { #[command(flatten)] pub body: MessageRawBodyArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -48,11 +42,9 @@ impl TemplateForwardCommand { let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let get_messages_kind = toml_account_config.get_messages_kind(); diff --git a/src/email/message/template/command/reply.rs b/src/email/message/template/command/reply.rs index 7276186..2a80e7f 100644 --- a/src/email/message/template/command/reply.rs +++ b/src/email/message/template/command/reply.rs @@ -3,8 +3,6 @@ use color_eyre::{eyre::eyre, Result}; use email::backend::feature::BackendFeatureSource; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -38,10 +36,6 @@ pub struct TemplateReplyCommand { #[command(flatten)] pub body: MessageRawBodyArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -53,11 +47,9 @@ impl TemplateReplyCommand { let folder = &self.folder.name; let id = self.envelope.id; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let get_messages_kind = toml_account_config.get_messages_kind(); diff --git a/src/email/message/template/command/save.rs b/src/email/message/template/command/save.rs index 1a91409..05ab816 100644 --- a/src/email/message/template/command/save.rs +++ b/src/email/message/template/command/save.rs @@ -5,8 +5,6 @@ use mml::MmlCompilerBuilder; use std::io::{self, BufRead, IsTerminal}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, email::template::arg::TemplateRawArg, folder::arg::name::FolderNameOptionalFlag, @@ -27,10 +25,6 @@ pub struct TemplateSaveCommand { #[command(flatten)] pub template: TemplateRawArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -41,11 +35,9 @@ impl TemplateSaveCommand { let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_message_kind = toml_account_config.add_message_kind(); diff --git a/src/email/message/template/command/send.rs b/src/email/message/template/command/send.rs index 1220c3c..3af49db 100644 --- a/src/email/message/template/command/send.rs +++ b/src/email/message/template/command/send.rs @@ -5,8 +5,6 @@ use mml::MmlCompilerBuilder; use std::io::{self, BufRead, IsTerminal}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, email::template::arg::TemplateRawArg, printer::Printer, @@ -23,10 +21,6 @@ pub struct TemplateSendCommand { #[command(flatten)] pub template: TemplateRawArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -35,11 +29,9 @@ impl TemplateSendCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing send template command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let send_message_kind = toml_account_config.send_message_kind().into_iter().chain( toml_account_config diff --git a/src/email/message/template/command/write.rs b/src/email/message/template/command/write.rs index 15536ec..98b4d02 100644 --- a/src/email/message/template/command/write.rs +++ b/src/email/message/template/command/write.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::message::Message; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, config::TomlConfig, email::template::arg::body::TemplateRawBodyArg, message::arg::header::HeaderRawArgs, @@ -23,10 +21,6 @@ pub struct TemplateWriteCommand { #[command(flatten)] pub body: TemplateRawBodyArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -35,11 +29,9 @@ impl TemplateWriteCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing write template command"); - let (_, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (_, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let tpl = Message::new_tpl_builder(account_config) .with_headers(self.headers.raw) diff --git a/src/folder/command/add.rs b/src/folder/command/add.rs index 1622d84..7d7b89c 100644 --- a/src/folder/command/add.rs +++ b/src/folder/command/add.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::{backend::feature::BackendFeatureSource, folder::add::AddFolder}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, @@ -19,10 +17,6 @@ pub struct AddFolderCommand { #[command(flatten)] pub folder: FolderNameArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -32,11 +26,9 @@ impl AddFolderCommand { info!("executing create folder command"); let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let add_folder_kind = toml_account_config.add_folder_kind(); diff --git a/src/folder/command/delete.rs b/src/folder/command/delete.rs index 3454372..97bc2d1 100644 --- a/src/folder/command/delete.rs +++ b/src/folder/command/delete.rs @@ -5,8 +5,6 @@ use inquire::Confirm; use std::process; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, @@ -21,10 +19,6 @@ pub struct FolderDeleteCommand { #[command(flatten)] pub folder: FolderNameArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -42,11 +36,9 @@ impl FolderDeleteCommand { process::exit(0); }; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let delete_folder_kind = toml_account_config.delete_folder_kind(); diff --git a/src/folder/command/expunge.rs b/src/folder/command/expunge.rs index e7f3ee2..82bca8f 100644 --- a/src/folder/command/expunge.rs +++ b/src/folder/command/expunge.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::{backend::feature::BackendFeatureSource, folder::expunge::ExpungeFolder}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, @@ -20,10 +18,6 @@ pub struct FolderExpungeCommand { #[command(flatten)] pub folder: FolderNameArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -33,11 +27,9 @@ impl FolderExpungeCommand { info!("executing expunge folder command"); let folder = &self.folder.name; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let expunge_folder_kind = toml_account_config.expunge_folder_kind(); diff --git a/src/folder/command/list.rs b/src/folder/command/list.rs index 3ed4391..6334375 100644 --- a/src/folder/command/list.rs +++ b/src/folder/command/list.rs @@ -3,8 +3,6 @@ use color_eyre::Result; use email::{backend::feature::BackendFeatureSource, folder::list::ListFolders}; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, @@ -18,10 +16,6 @@ use crate::{ /// This command allows you to list all exsting folders. #[derive(Debug, Parser)] pub struct FolderListCommand { - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, @@ -38,11 +32,9 @@ impl FolderListCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing list folders command"); - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let list_folders_kind = toml_account_config.list_folders_kind(); diff --git a/src/folder/command/purge.rs b/src/folder/command/purge.rs index 1db9630..568abc0 100644 --- a/src/folder/command/purge.rs +++ b/src/folder/command/purge.rs @@ -4,8 +4,6 @@ use email::{backend::feature::BackendFeatureSource, folder::purge::PurgeFolder}; use std::process; use tracing::info; -#[cfg(feature = "account-sync")] -use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, @@ -20,10 +18,6 @@ pub struct FolderPurgeCommand { #[command(flatten)] pub folder: FolderNameArg, - #[cfg(feature = "account-sync")] - #[command(flatten)] - pub cache: CacheDisableFlag, - #[command(flatten)] pub account: AccountNameFlag, } @@ -42,11 +36,9 @@ impl FolderPurgeCommand { process::exit(0); }; - let (toml_account_config, account_config) = config.clone().into_account_configs( - self.account.name.as_deref(), - #[cfg(feature = "account-sync")] - self.cache.disable, - )?; + let (toml_account_config, account_config) = config + .clone() + .into_account_configs(self.account.name.as_deref())?; let purge_folder_kind = toml_account_config.purge_folder_kind(); diff --git a/src/folder/config.rs b/src/folder/config.rs index 69a3bb4..da085c4 100644 --- a/src/folder/config.rs +++ b/src/folder/config.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "account-sync")] -use email::folder::sync::config::FolderSyncConfig; use serde::{Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; @@ -14,8 +12,6 @@ pub struct FolderConfig { pub expunge: Option, pub purge: Option, pub delete: Option, - #[cfg(feature = "account-sync")] - pub sync: Option, } impl FolderConfig { diff --git a/src/imap/mod.rs b/src/imap/mod.rs index 73818b4..7df0104 100644 --- a/src/imap/mod.rs +++ b/src/imap/mod.rs @@ -1 +1,2 @@ +#[cfg(feature = "wizard")] pub(crate) mod wizard; diff --git a/src/imap/wizard.rs b/src/imap/wizard.rs index d3e4e91..3159780 100644 --- a/src/imap/wizard.rs +++ b/src/imap/wizard.rs @@ -1,18 +1,20 @@ use color_eyre::Result; -#[cfg(feature = "account-discovery")] -use email::account::discover::config::{AuthenticationType, AutoConfig, SecurityType, ServerType}; +use email::autoconfig::config::{AutoConfig, SecurityType, ServerType}; +#[cfg(feature = "oauth2")] use email::{ - account::config::{ - oauth2::{OAuth2Config, OAuth2Method, OAuth2Scopes}, - passwd::PasswdConfig, - }, + account::config::oauth2::{OAuth2Config, OAuth2Method, OAuth2Scopes}, + autoconfig::config::AuthenticationType, +}; +use email::{ + account::config::passwd::PasswdConfig, imap::config::{ImapAuthConfig, ImapConfig, ImapEncryptionKind}, }; use inquire::validator::{ErrorMessage, StringValidator, Validation}; +#[cfg(feature = "oauth2")] use oauth::v2_0::{AuthorizationCodeGrant, Client}; use secret::Secret; -use crate::{backend::config::BackendConfig, ui::prompt, wizard_log}; +use crate::{backend::config::BackendConfig, ui::prompt}; const ENCRYPTIONS: &[ImapEncryptionKind] = &[ ImapEncryptionKind::Tls, @@ -20,11 +22,13 @@ const ENCRYPTIONS: &[ImapEncryptionKind] = &[ ImapEncryptionKind::None, ]; -const XOAUTH2: &str = "XOAUTH2"; -const OAUTHBEARER: &str = "OAUTHBEARER"; -const OAUTH2_MECHANISMS: &[&str] = &[XOAUTH2, OAUTHBEARER]; - -const SECRETS: &[&str] = &[KEYRING, RAW, CMD]; +const SECRETS: &[&str] = &[ + #[cfg(feature = "keyring")] + KEYRING, + RAW, + CMD, +]; +#[cfg(feature = "keyring")] const KEYRING: &str = "Ask my password, then save it in my system's global keyring"; const RAW: &str = "Ask my password, then save it in the configuration file (not safe)"; const CMD: &str = "Ask me a shell command that exposes my password"; @@ -49,16 +53,14 @@ impl StringValidator for U16Validator { } } -#[cfg(feature = "account-discovery")] pub(crate) async fn configure( account_name: &str, email: &str, autoconfig: Option<&AutoConfig>, ) -> Result { use color_eyre::eyre::OptionExt as _; - use inquire::{validator::MinLengthValidator, Confirm, Password, Select, Text}; + use inquire::{validator, Select, Text}; - let autoconfig_oauth2 = autoconfig.and_then(|c| c.oauth2()); let autoconfig_server = autoconfig.and_then(|c| { c.email_provider() .incoming_servers() @@ -93,7 +95,7 @@ pub(crate) async fn configure( ImapEncryptionKind::None => 2, }; - let encryption_idx = Select::new("IMAP encryption", ENCRYPTIONS.to_vec()) + let encryption_kind = Select::new("IMAP encryption", ENCRYPTIONS.to_vec()) .with_starting_cursor(default_encryption_idx) .prompt_skippable()?; @@ -101,28 +103,28 @@ pub(crate) async fn configure( .and_then(|s| s.port()) .map(ToOwned::to_owned) .unwrap_or_else(|| match &autoconfig_encryption { - ImapEncryptionKind::Tls => 993, - ImapEncryptionKind::StartTls => 143, - ImapEncryptionKind::None => 143, + ImapEncryptionKind::Tls => 465, + ImapEncryptionKind::StartTls => 587, + ImapEncryptionKind::None => 25, }); - let (encryption, default_port) = match encryption_idx { - Some(enc_kind) - if &enc_kind + let (encryption, default_port) = match encryption_kind { + Some(idx) + if &idx == ENCRYPTIONS.get(default_encryption_idx).ok_or_eyre( - "something impossible happened while selecting the encryption of imap.", + "something impossible happened during finding default match for encryption.", )? => { (Some(autoconfig_encryption), autoconfig_port) } - Some(ImapEncryptionKind::Tls) => (Some(ImapEncryptionKind::Tls), 993), - Some(ImapEncryptionKind::StartTls) => (Some(ImapEncryptionKind::StartTls), 143), - _ => (Some(ImapEncryptionKind::None), 143), + Some(ImapEncryptionKind::Tls) => (Some(ImapEncryptionKind::Tls), 465), + Some(ImapEncryptionKind::StartTls) => (Some(ImapEncryptionKind::StartTls), 587), + _ => (Some(ImapEncryptionKind::None), 25), }; let port = Text::new("IMAP port") .with_validators(&[ - Box::new(MinLengthValidator::new(1)), + Box::new(validator::MinLengthValidator::new(1)), Box::new(U16Validator {}), ]) .with_default(&default_port.to_string()) @@ -141,173 +143,167 @@ pub(crate) async fn configure( .with_default(&default_login) .prompt()?; - let default_oauth2_enabled = autoconfig_server - .and_then(|imap| { - imap.authentication_type() - .into_iter() - .find_map(|t| Option::from(matches!(t, AuthenticationType::OAuth2))) - }) - .filter(|_| autoconfig_oauth2.is_some()) - .unwrap_or_default(); + #[cfg(feature = "oauth2")] + let auth = { + use inquire::{Confirm, Password}; - let oauth2_enabled = Confirm::new("Would you like to enable OAuth 2.0?") - .with_default(default_oauth2_enabled) - .prompt_skippable()? - .unwrap_or_default(); + const XOAUTH2: &str = "XOAUTH2"; + const OAUTHBEARER: &str = "OAUTHBEARER"; + const OAUTH2_MECHANISMS: &[&str] = &[XOAUTH2, OAUTHBEARER]; - let auth = if oauth2_enabled { - let mut config = OAuth2Config::default(); - let redirect_host = OAuth2Config::LOCALHOST.to_owned(); - let redirect_port = OAuth2Config::get_first_available_port()?; + let autoconfig_oauth2 = autoconfig.and_then(|c| c.oauth2()); - let method_idx = Select::new("IMAP OAuth 2.0 mechanism", OAUTH2_MECHANISMS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - config.method = match method_idx { - Some(XOAUTH2) => OAuth2Method::XOAuth2, - Some(OAUTHBEARER) => OAuth2Method::OAuthBearer, - _ => OAuth2Method::XOAuth2, - }; - - config.client_id = Text::new("IMAP OAuth 2.0 client id").prompt()?; - - let client_secret: String = Password::new("IMAP OAuth 2.0 client secret").prompt()?; - config.client_secret = - Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-client-secret"))?; - config - .client_secret - .set_only_keyring(&client_secret) - .await?; - - let default_auth_url = autoconfig_oauth2 - .map(|o| o.auth_url().to_owned()) - .unwrap_or_default(); - config.auth_url = Text::new("IMAP OAuth 2.0 authorization URL") - .with_default(&default_auth_url) - .prompt()?; - - let default_token_url = autoconfig_oauth2 - .map(|o| o.token_url().to_owned()) - .unwrap_or_default(); - config.token_url = Text::new("IMAP OAuth 2.0 token URL") - .with_default(&default_token_url) - .prompt()?; - - let autoconfig_scopes = autoconfig_oauth2.map(|o| o.scope()); - - let prompt_scope = |prompt: &str| -> Result> { - Ok(match &autoconfig_scopes { - Some(scopes) => Select::new(prompt, scopes.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()? - .map(ToOwned::to_owned), - None => { - Some(Text::new(prompt).prompt()?.to_owned()).filter(|scope| !scope.is_empty()) - } + let default_oauth2_enabled = autoconfig_server + .and_then(|imap| { + imap.authentication_type() + .into_iter() + .find_map(|t| Option::from(matches!(t, AuthenticationType::OAuth2))) }) - }; + .filter(|_| autoconfig_oauth2.is_some()) + .unwrap_or_default(); - if let Some(scope) = prompt_scope("IMAP OAuth 2.0 main scope")? { - config.scopes = OAuth2Scopes::Scope(scope); - } + let oauth2_enabled = Confirm::new("Would you like to enable OAuth 2.0?") + .with_default(default_oauth2_enabled) + .prompt_skippable()? + .unwrap_or_default(); - let confirm_additional_scope = || -> Result { - let confirm = Confirm::new("Would you like to add more IMAP OAuth 2.0 scopes?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); + if oauth2_enabled { + let mut config = OAuth2Config::default(); + let redirect_host = OAuth2Config::LOCALHOST; + let redirect_port = OAuth2Config::get_first_available_port()?; - Ok(confirm) - }; + let method_idx = Select::new("IMAP OAuth 2.0 mechanism", OAUTH2_MECHANISMS.to_vec()) + .with_starting_cursor(0) + .prompt_skippable()?; - while confirm_additional_scope()? { - let mut scopes = match config.scopes { - OAuth2Scopes::Scope(scope) => vec![scope], - OAuth2Scopes::Scopes(scopes) => scopes, + config.method = match method_idx { + Some(choice) if choice == XOAUTH2 => OAuth2Method::XOAuth2, + Some(choice) if choice == OAUTHBEARER => OAuth2Method::OAuthBearer, + _ => OAuth2Method::XOAuth2, }; - if let Some(scope) = prompt_scope("Additional IMAP OAuth 2.0 scope")? { - scopes.push(scope) + config.client_id = Text::new("IMAP OAuth 2.0 client id").prompt()?; + + let client_secret: String = Password::new("IMAP OAuth 2.0 client secret") + .with_display_mode(inquire::PasswordDisplayMode::Masked) + .prompt()?; + config.client_secret = + Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-client-secret"))?; + config + .client_secret + .set_only_keyring(&client_secret) + .await?; + + let default_auth_url = autoconfig_oauth2 + .map(|o| o.auth_url().to_owned()) + .unwrap_or_default(); + config.auth_url = Text::new("IMAP OAuth 2.0 authorization URL") + .with_default(&default_auth_url) + .prompt()?; + + let default_token_url = autoconfig_oauth2 + .map(|o| o.token_url().to_owned()) + .unwrap_or_default(); + config.token_url = Text::new("IMAP OAuth 2.0 token URL") + .with_default(&default_token_url) + .prompt()?; + + let autoconfig_scopes = autoconfig_oauth2.map(|o| o.scope()); + + let prompt_scope = |prompt: &str| -> Result> { + Ok(match &autoconfig_scopes { + Some(scopes) => Select::new(prompt, scopes.to_vec()) + .with_starting_cursor(0) + .prompt_skippable()? + .map(ToOwned::to_owned), + None => Some(Text::new(prompt).prompt()?).filter(|scope| !scope.is_empty()), + }) + }; + + if let Some(scope) = prompt_scope("IMAP OAuth 2.0 main scope")? { + config.scopes = OAuth2Scopes::Scope(scope); } - config.scopes = OAuth2Scopes::Scopes(scopes); - } + let confirm_additional_scope = || -> Result { + let confirm = Confirm::new("Would you like to add more IMAP OAuth 2.0 scopes?") + .with_default(false) + .prompt_skippable()? + .unwrap_or_default(); - config.pkce = Confirm::new("Would you like to enable PKCE verification?") - .with_default(true) - .prompt_skippable()? - .unwrap_or(true); + Ok(confirm) + }; - wizard_log!("To complete your OAuth 2.0 setup, click on the following link:"); + while confirm_additional_scope()? { + let mut scopes = match config.scopes { + OAuth2Scopes::Scope(scope) => vec![scope], + OAuth2Scopes::Scopes(scopes) => scopes, + }; - let client = Client::new( - config.client_id.clone(), - client_secret, - config.auth_url.clone(), - config.token_url.clone(), - )? - .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port) - .build()?; + if let Some(scope) = prompt_scope("Additional IMAP OAuth 2.0 scope")? { + scopes.push(scope) + } - let mut auth_code_grant = AuthorizationCodeGrant::new() + config.scopes = OAuth2Scopes::Scopes(scopes); + } + + config.pkce = Confirm::new("Would you like to enable PKCE verification?") + .with_default(true) + .prompt_skippable()? + .unwrap_or(true); + + crate::wizard_log!("To complete your OAuth 2.0 setup, click on the following link:"); + + let client = Client::new( + config.client_id.clone(), + client_secret, + config.auth_url.clone(), + config.token_url.clone(), + )? .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port); + .with_redirect_port(redirect_port) + .build()?; - if config.pkce { - auth_code_grant = auth_code_grant.with_pkce(); - } + let mut auth_code_grant = AuthorizationCodeGrant::new() + .with_redirect_host(redirect_host.to_owned()) + .with_redirect_port(redirect_port); - for scope in config.scopes.clone() { - auth_code_grant = auth_code_grant.with_scope(scope); - } - - let (redirect_url, csrf_token) = auth_code_grant.get_redirect_url(&client); - - println!("{redirect_url}"); - println!(); - - let (access_token, refresh_token) = auth_code_grant - .wait_for_redirection(&client, csrf_token) - .await?; - - config.access_token = - Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-access-token"))?; - config.access_token.set_only_keyring(access_token).await?; - - if let Some(refresh_token) = &refresh_token { - config.refresh_token = - Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-refresh-token"))?; - config.refresh_token.set_only_keyring(refresh_token).await?; - } - - ImapAuthConfig::OAuth2(config) - } else { - let secret_idx = Select::new("IMAP authentication strategy", SECRETS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - let secret = match secret_idx { - Some(KEYRING) => { - let secret = Secret::try_new_keyring_entry(format!("{account_name}-imap-passwd"))?; - secret - .set_only_keyring(prompt::passwd("IMAP password")?) - .await?; - secret + if config.pkce { + auth_code_grant = auth_code_grant.with_pkce(); } - Some(RAW) => Secret::new_raw(prompt::passwd("IMAP password")?), - Some(CMD) => Secret::new_command( - Text::new("Shell command") - .with_default(&format!("pass show {account_name}-imap-passwd")) - .prompt()?, - ), - _ => Default::default(), - }; - ImapAuthConfig::Passwd(PasswdConfig(secret)) + for scope in config.scopes.clone() { + auth_code_grant = auth_code_grant.with_scope(scope); + } + + let (redirect_url, csrf_token) = auth_code_grant.get_redirect_url(&client); + + println!("{redirect_url}"); + println!(); + + let (access_token, refresh_token) = auth_code_grant + .wait_for_redirection(&client, csrf_token) + .await?; + + config.access_token = + Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-access-token"))?; + config.access_token.set_only_keyring(access_token).await?; + + if let Some(refresh_token) = &refresh_token { + config.refresh_token = Secret::try_new_keyring_entry(format!( + "{account_name}-imap-oauth2-refresh-token" + ))?; + config.refresh_token.set_only_keyring(refresh_token).await?; + } + + ImapAuthConfig::OAuth2(config) + } else { + configure_passwd(account_name).await? + } }; + #[cfg(not(feature = "oauth2"))] + let auth = configure_passwd(account_name).await?; + let config = ImapConfig { host, port, @@ -320,191 +316,30 @@ pub(crate) async fn configure( Ok(BackendConfig::Imap(config)) } -#[cfg(not(feature = "account-discovery"))] -pub(crate) async fn configure(account_name: &str, email: &str) -> Result { - use inquire::{ - validator::MinLengthValidator, Confirm, Password, PasswordDisplayMode, Select, Text, - }; +pub(crate) async fn configure_passwd(account_name: &str) -> Result { + use inquire::{Select, Text}; - let default_host = format!("imap.{}", email.rsplit_once('@').unwrap().1); - - let host = Text::new("IMAP hostname") - .with_default(&default_host) - .prompt()?; - - let encryption_idx = Select::new("IMAP encryption", ENCRYPTIONS.to_vec()) + let secret_idx = Select::new("IMAP authentication strategy", SECRETS.to_vec()) .with_starting_cursor(0) .prompt_skippable()?; - let (encryption, default_port) = match encryption_idx { - Some(ImapEncryptionKind::Tls) => (Some(ImapEncryptionKind::Tls), 993), - Some(ImapEncryptionKind::StartTls) => (Some(ImapEncryptionKind::StartTls), 143), - _ => (Some(ImapEncryptionKind::None), 143), + let secret = match secret_idx { + #[cfg(feature = "keyring")] + Some(sec) if sec == KEYRING => { + let secret = Secret::try_new_keyring_entry(format!("{account_name}-imap-passwd"))?; + secret + .set_only_keyring(prompt::passwd("IMAP password")?) + .await?; + secret + } + Some(sec) if sec == RAW => Secret::new_raw(prompt::passwd("IMAP password")?), + Some(sec) if sec == CMD => Secret::new_command( + Text::new("Shell command") + .with_default(&format!("pass show {account_name}-imap-passwd")) + .prompt()?, + ), + _ => Default::default(), }; - let port = Text::new("IMAP port") - .with_validators(&[ - Box::new(MinLengthValidator::new(1)), - Box::new(U16Validator {}), - ]) - .with_default(&default_port.to_string()) - .prompt() - .map(|input| input.parse::().unwrap())?; - - let default_login = email.to_owned(); - - let login = Text::new("IMAP login") - .with_default(&default_login) - .prompt()?; - - let oauth2_enabled = Confirm::new("Would you like to enable OAuth 2.0?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); - - let auth = if oauth2_enabled { - let mut config = OAuth2Config::default(); - let redirect_host = OAuth2Config::LOCALHOST.to_owned(); - let redirect_port = OAuth2Config::get_first_available_port()?; - - let method_idx = Select::new("IMAP OAuth 2.0 mechanism", OAUTH2_MECHANISMS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - config.method = match method_idx { - Some(XOAUTH2) => OAuth2Method::XOAuth2, - Some(OAUTHBEARER) => OAuth2Method::OAuthBearer, - _ => OAuth2Method::XOAuth2, - }; - - config.client_id = Text::new("IMAP OAuth 2.0 client id").prompt()?; - - let client_secret: String = Password::new("IMAP OAuth 2.0 client secret") - .with_display_mode(PasswordDisplayMode::Masked) - .prompt()?; - config.client_secret = - Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-client-secret"))?; - config - .client_secret - .set_only_keyring(&client_secret) - .await?; - - config.auth_url = Text::new("IMAP OAuth 2.0 authorization URL").prompt()?; - - config.token_url = Text::new("IMAP OAuth 2.0 token URL").prompt()?; - - let prompt_scope = |prompt: &str| -> Result> { - Ok(Some(Text::new(prompt).prompt()?.to_owned()).filter(|scope| !scope.is_empty())) - }; - - if let Some(scope) = prompt_scope("IMAP OAuth 2.0 main scope")? { - config.scopes = OAuth2Scopes::Scope(scope); - } - - let confirm_additional_scope = || -> Result { - let confirm = Confirm::new("Would you like to add more IMAP OAuth 2.0 scopes?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); - - Ok(confirm) - }; - - while confirm_additional_scope()? { - let mut scopes = match config.scopes { - OAuth2Scopes::Scope(scope) => vec![scope], - OAuth2Scopes::Scopes(scopes) => scopes, - }; - - if let Some(scope) = prompt_scope("Additional IMAP OAuth 2.0 scope")? { - scopes.push(scope) - } - - config.scopes = OAuth2Scopes::Scopes(scopes); - } - - config.pkce = Confirm::new("Would you like to enable PKCE verification?") - .with_default(true) - .prompt_skippable()? - .unwrap_or(true); - - wizard_log!("To complete your OAuth 2.0 setup, click on the following link:"); - - let client = Client::new( - config.client_id.clone(), - client_secret, - config.auth_url.clone(), - config.token_url.clone(), - )? - .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port) - .build()?; - - let mut auth_code_grant = AuthorizationCodeGrant::new() - .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port); - - if config.pkce { - auth_code_grant = auth_code_grant.with_pkce(); - } - - for scope in config.scopes.clone() { - auth_code_grant = auth_code_grant.with_scope(scope); - } - - let (redirect_url, csrf_token) = auth_code_grant.get_redirect_url(&client); - - println!("{redirect_url}"); - println!(); - - let (access_token, refresh_token) = auth_code_grant - .wait_for_redirection(&client, csrf_token) - .await?; - - config.access_token = - Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-access-token"))?; - config.access_token.set_only_keyring(access_token).await?; - - if let Some(refresh_token) = &refresh_token { - config.refresh_token = - Secret::try_new_keyring_entry(format!("{account_name}-imap-oauth2-refresh-token"))?; - config.refresh_token.set_only_keyring(refresh_token).await?; - } - - ImapAuthConfig::OAuth2(config) - } else { - let secret_idx = Select::new("IMAP authentication strategy", SECRETS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - let secret = match secret_idx { - Some(KEYRING) => { - let secret = Secret::try_new_keyring_entry(format!("{account_name}-imap-passwd"))?; - secret - .set_only_keyring(prompt::passwd("IMAP password")?) - .await?; - secret - } - Some(RAW) => Secret::new_raw(prompt::passwd("IMAP password")?), - Some(CMD) => Secret::new_command( - Text::new("Shell command") - .with_default(&format!("pass show {account_name}-imap-passwd")) - .prompt()?, - ), - _ => Default::default(), - }; - - ImapAuthConfig::Passwd(PasswdConfig(secret)) - }; - - let config = ImapConfig { - host, - port, - encryption, - login, - auth, - watch: None, - }; - - Ok(BackendConfig::Imap(config)) + Ok(ImapAuthConfig::Passwd(PasswdConfig(secret))) } diff --git a/src/maildir/mod.rs b/src/maildir/mod.rs index 73818b4..7df0104 100644 --- a/src/maildir/mod.rs +++ b/src/maildir/mod.rs @@ -1 +1,2 @@ +#[cfg(feature = "wizard")] pub(crate) mod wizard; diff --git a/src/smtp/mod.rs b/src/smtp/mod.rs index 73818b4..7df0104 100644 --- a/src/smtp/mod.rs +++ b/src/smtp/mod.rs @@ -1 +1,2 @@ +#[cfg(feature = "wizard")] pub(crate) mod wizard; diff --git a/src/smtp/wizard.rs b/src/smtp/wizard.rs index d682c7c..9879bdb 100644 --- a/src/smtp/wizard.rs +++ b/src/smtp/wizard.rs @@ -1,18 +1,20 @@ use color_eyre::Result; -#[cfg(feature = "account-discovery")] -use email::account::discover::config::{AuthenticationType, AutoConfig, SecurityType, ServerType}; +use email::autoconfig::config::{AutoConfig, SecurityType, ServerType}; +#[cfg(feature = "oauth2")] use email::{ - account::config::{ - oauth2::{OAuth2Config, OAuth2Method, OAuth2Scopes}, - passwd::PasswdConfig, - }, + account::config::oauth2::{OAuth2Config, OAuth2Method, OAuth2Scopes}, + autoconfig::config::AuthenticationType, +}; +use email::{ + account::config::passwd::PasswdConfig, smtp::config::{SmtpAuthConfig, SmtpConfig, SmtpEncryptionKind}, }; use inquire::validator::{ErrorMessage, StringValidator, Validation}; +#[cfg(feature = "oauth2")] use oauth::v2_0::{AuthorizationCodeGrant, Client}; use secret::Secret; -use crate::{backend::config::BackendConfig, ui::prompt, wizard_log}; +use crate::{backend::config::BackendConfig, ui::prompt}; const ENCRYPTIONS: &[SmtpEncryptionKind] = &[ SmtpEncryptionKind::Tls, @@ -20,11 +22,13 @@ const ENCRYPTIONS: &[SmtpEncryptionKind] = &[ SmtpEncryptionKind::None, ]; -const XOAUTH2: &str = "XOAUTH2"; -const OAUTHBEARER: &str = "OAUTHBEARER"; -const OAUTH2_MECHANISMS: &[&str] = &[XOAUTH2, OAUTHBEARER]; - -const SECRETS: &[&str] = &[KEYRING, RAW, CMD]; +const SECRETS: &[&str] = &[ + #[cfg(feature = "keyring")] + KEYRING, + RAW, + CMD, +]; +#[cfg(feature = "keyring")] const KEYRING: &str = "Ask my password, then save it in my system's global keyring"; const RAW: &str = "Ask my password, then save it in the configuration file (not safe)"; const CMD: &str = "Ask me a shell command that exposes my password"; @@ -49,16 +53,14 @@ impl StringValidator for U16Validator { } } -#[cfg(feature = "account-discovery")] pub(crate) async fn configure( account_name: &str, email: &str, autoconfig: Option<&AutoConfig>, ) -> Result { use color_eyre::eyre::OptionExt as _; - use inquire::{validator, Confirm, Password, Select, Text}; + use inquire::{validator, Select, Text}; - let autoconfig_oauth2 = autoconfig.and_then(|c| c.oauth2()); let autoconfig_server = autoconfig.and_then(|c| { c.email_provider() .outgoing_servers() @@ -141,173 +143,167 @@ pub(crate) async fn configure( .with_default(&default_login) .prompt()?; - let default_oauth2_enabled = autoconfig_server - .and_then(|smtp| { - smtp.authentication_type() - .into_iter() - .find_map(|t| Option::from(matches!(t, AuthenticationType::OAuth2))) - }) - .filter(|_| autoconfig_oauth2.is_some()) - .unwrap_or_default(); + #[cfg(feature = "oauth2")] + let auth = { + use inquire::{Confirm, Password}; - let oauth2_enabled = Confirm::new("Would you like to enable OAuth 2.0?") - .with_default(default_oauth2_enabled) - .prompt_skippable()? - .unwrap_or_default(); + const XOAUTH2: &str = "XOAUTH2"; + const OAUTHBEARER: &str = "OAUTHBEARER"; + const OAUTH2_MECHANISMS: &[&str] = &[XOAUTH2, OAUTHBEARER]; - let auth = if oauth2_enabled { - let mut config = OAuth2Config::default(); - let redirect_host = OAuth2Config::LOCALHOST; - let redirect_port = OAuth2Config::get_first_available_port()?; + let autoconfig_oauth2 = autoconfig.and_then(|c| c.oauth2()); - let method_idx = Select::new("SMTP OAuth 2.0 mechanism", OAUTH2_MECHANISMS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - config.method = match method_idx { - Some(choice) if choice == XOAUTH2 => OAuth2Method::XOAuth2, - Some(choice) if choice == OAUTHBEARER => OAuth2Method::OAuthBearer, - _ => OAuth2Method::XOAuth2, - }; - - config.client_id = Text::new("SMTP OAuth 2.0 client id").prompt()?; - - let client_secret: String = Password::new("SMTP OAuth 2.0 client secret") - .with_display_mode(inquire::PasswordDisplayMode::Masked) - .prompt()?; - config.client_secret = - Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-client-secret"))?; - config - .client_secret - .set_only_keyring(&client_secret) - .await?; - - let default_auth_url = autoconfig_oauth2 - .map(|o| o.auth_url().to_owned()) - .unwrap_or_default(); - config.auth_url = Text::new("SMTP OAuth 2.0 authorization URL") - .with_default(&default_auth_url) - .prompt()?; - - let default_token_url = autoconfig_oauth2 - .map(|o| o.token_url().to_owned()) - .unwrap_or_default(); - config.token_url = Text::new("SMTP OAuth 2.0 token URL") - .with_default(&default_token_url) - .prompt()?; - - let autoconfig_scopes = autoconfig_oauth2.map(|o| o.scope()); - - let prompt_scope = |prompt: &str| -> Result> { - Ok(match &autoconfig_scopes { - Some(scopes) => Select::new(prompt, scopes.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()? - .map(ToOwned::to_owned), - None => Some(Text::new(prompt).prompt()?).filter(|scope| !scope.is_empty()), + let default_oauth2_enabled = autoconfig_server + .and_then(|smtp| { + smtp.authentication_type() + .into_iter() + .find_map(|t| Option::from(matches!(t, AuthenticationType::OAuth2))) }) - }; + .filter(|_| autoconfig_oauth2.is_some()) + .unwrap_or_default(); - if let Some(scope) = prompt_scope("SMTP OAuth 2.0 main scope")? { - config.scopes = OAuth2Scopes::Scope(scope); - } + let oauth2_enabled = Confirm::new("Would you like to enable OAuth 2.0?") + .with_default(default_oauth2_enabled) + .prompt_skippable()? + .unwrap_or_default(); - let confirm_additional_scope = || -> Result { - let confirm = Confirm::new("Would you like to add more SMTP OAuth 2.0 scopes?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); + if oauth2_enabled { + let mut config = OAuth2Config::default(); + let redirect_host = OAuth2Config::LOCALHOST; + let redirect_port = OAuth2Config::get_first_available_port()?; - Ok(confirm) - }; + let method_idx = Select::new("SMTP OAuth 2.0 mechanism", OAUTH2_MECHANISMS.to_vec()) + .with_starting_cursor(0) + .prompt_skippable()?; - while confirm_additional_scope()? { - let mut scopes = match config.scopes { - OAuth2Scopes::Scope(scope) => vec![scope], - OAuth2Scopes::Scopes(scopes) => scopes, + config.method = match method_idx { + Some(choice) if choice == XOAUTH2 => OAuth2Method::XOAuth2, + Some(choice) if choice == OAUTHBEARER => OAuth2Method::OAuthBearer, + _ => OAuth2Method::XOAuth2, }; - if let Some(scope) = prompt_scope("Additional SMTP OAuth 2.0 scope")? { - scopes.push(scope) + config.client_id = Text::new("SMTP OAuth 2.0 client id").prompt()?; + + let client_secret: String = Password::new("SMTP OAuth 2.0 client secret") + .with_display_mode(inquire::PasswordDisplayMode::Masked) + .prompt()?; + config.client_secret = + Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-client-secret"))?; + config + .client_secret + .set_only_keyring(&client_secret) + .await?; + + let default_auth_url = autoconfig_oauth2 + .map(|o| o.auth_url().to_owned()) + .unwrap_or_default(); + config.auth_url = Text::new("SMTP OAuth 2.0 authorization URL") + .with_default(&default_auth_url) + .prompt()?; + + let default_token_url = autoconfig_oauth2 + .map(|o| o.token_url().to_owned()) + .unwrap_or_default(); + config.token_url = Text::new("SMTP OAuth 2.0 token URL") + .with_default(&default_token_url) + .prompt()?; + + let autoconfig_scopes = autoconfig_oauth2.map(|o| o.scope()); + + let prompt_scope = |prompt: &str| -> Result> { + Ok(match &autoconfig_scopes { + Some(scopes) => Select::new(prompt, scopes.to_vec()) + .with_starting_cursor(0) + .prompt_skippable()? + .map(ToOwned::to_owned), + None => Some(Text::new(prompt).prompt()?).filter(|scope| !scope.is_empty()), + }) + }; + + if let Some(scope) = prompt_scope("SMTP OAuth 2.0 main scope")? { + config.scopes = OAuth2Scopes::Scope(scope); } - config.scopes = OAuth2Scopes::Scopes(scopes); - } + let confirm_additional_scope = || -> Result { + let confirm = Confirm::new("Would you like to add more SMTP OAuth 2.0 scopes?") + .with_default(false) + .prompt_skippable()? + .unwrap_or_default(); - config.pkce = Confirm::new("Would you like to enable PKCE verification?") - .with_default(true) - .prompt_skippable()? - .unwrap_or(true); + Ok(confirm) + }; - wizard_log!("To complete your OAuth 2.0 setup, click on the following link:"); + while confirm_additional_scope()? { + let mut scopes = match config.scopes { + OAuth2Scopes::Scope(scope) => vec![scope], + OAuth2Scopes::Scopes(scopes) => scopes, + }; - let client = Client::new( - config.client_id.clone(), - client_secret, - config.auth_url.clone(), - config.token_url.clone(), - )? - .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port) - .build()?; + if let Some(scope) = prompt_scope("Additional SMTP OAuth 2.0 scope")? { + scopes.push(scope) + } - let mut auth_code_grant = AuthorizationCodeGrant::new() + config.scopes = OAuth2Scopes::Scopes(scopes); + } + + config.pkce = Confirm::new("Would you like to enable PKCE verification?") + .with_default(true) + .prompt_skippable()? + .unwrap_or(true); + + crate::wizard_log!("To complete your OAuth 2.0 setup, click on the following link:"); + + let client = Client::new( + config.client_id.clone(), + client_secret, + config.auth_url.clone(), + config.token_url.clone(), + )? .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port); + .with_redirect_port(redirect_port) + .build()?; - if config.pkce { - auth_code_grant = auth_code_grant.with_pkce(); - } + let mut auth_code_grant = AuthorizationCodeGrant::new() + .with_redirect_host(redirect_host.to_owned()) + .with_redirect_port(redirect_port); - for scope in config.scopes.clone() { - auth_code_grant = auth_code_grant.with_scope(scope); - } - - let (redirect_url, csrf_token) = auth_code_grant.get_redirect_url(&client); - - println!("{redirect_url}"); - println!(); - - let (access_token, refresh_token) = auth_code_grant - .wait_for_redirection(&client, csrf_token) - .await?; - - config.access_token = - Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-access-token"))?; - config.access_token.set_only_keyring(access_token).await?; - - if let Some(refresh_token) = &refresh_token { - config.refresh_token = - Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-refresh-token"))?; - config.refresh_token.set_only_keyring(refresh_token).await?; - } - - SmtpAuthConfig::OAuth2(config) - } else { - let secret_idx = Select::new("SMTP authentication strategy", SECRETS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - let secret = match secret_idx { - Some(sec) if sec == KEYRING => { - let secret = Secret::try_new_keyring_entry(format!("{account_name}-smtp-passwd"))?; - secret - .set_only_keyring(prompt::passwd("SMTP password")?) - .await?; - secret + if config.pkce { + auth_code_grant = auth_code_grant.with_pkce(); } - Some(sec) if sec == RAW => Secret::new_raw(prompt::passwd("SMTP password")?), - Some(sec) if sec == CMD => Secret::new_command( - Text::new("Shell command") - .with_default(&format!("pass show {account_name}-smtp-passwd")) - .prompt()?, - ), - _ => Default::default(), - }; - SmtpAuthConfig::Passwd(PasswdConfig(secret)) + for scope in config.scopes.clone() { + auth_code_grant = auth_code_grant.with_scope(scope); + } + + let (redirect_url, csrf_token) = auth_code_grant.get_redirect_url(&client); + + println!("{redirect_url}"); + println!(); + + let (access_token, refresh_token) = auth_code_grant + .wait_for_redirection(&client, csrf_token) + .await?; + + config.access_token = + Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-access-token"))?; + config.access_token.set_only_keyring(access_token).await?; + + if let Some(refresh_token) = &refresh_token { + config.refresh_token = Secret::try_new_keyring_entry(format!( + "{account_name}-smtp-oauth2-refresh-token" + ))?; + config.refresh_token.set_only_keyring(refresh_token).await?; + } + + SmtpAuthConfig::OAuth2(config) + } else { + configure_passwd(account_name).await? + } }; + #[cfg(not(feature = "oauth2"))] + let auth = configure_passwd(account_name).await?; + let config = SmtpConfig { host, port, @@ -319,188 +315,30 @@ pub(crate) async fn configure( Ok(BackendConfig::Smtp(config)) } -#[cfg(not(feature = "account-discovery"))] -pub(crate) async fn configure(account_name: &str, email: &str) -> Result { - use inquire::{validator::MinLengthValidator, Confirm, Password, Select, Text}; +pub(crate) async fn configure_passwd(account_name: &str) -> Result { + use inquire::{Select, Text}; - let default_host = format!("smtp.{}", email.rsplit_once('@').unwrap().1); - - let host = Text::new("SMTP hostname") - .with_default(&default_host) - .prompt()?; - - let encryption_idx = Select::new("SMTP encryption", ENCRYPTIONS.to_vec()) + let secret_idx = Select::new("SMTP authentication strategy", SECRETS.to_vec()) .with_starting_cursor(0) .prompt_skippable()?; - let (encryption, default_port) = match encryption_idx { - Some(SmtpEncryptionKind::Tls) => (Some(SmtpEncryptionKind::Tls), 465), - Some(SmtpEncryptionKind::StartTls) => (Some(SmtpEncryptionKind::StartTls), 587), - _ => (Some(SmtpEncryptionKind::None), 25), + let secret = match secret_idx { + #[cfg(feature = "keyring")] + Some(sec) if sec == KEYRING => { + let secret = Secret::try_new_keyring_entry(format!("{account_name}-smtp-passwd"))?; + secret + .set_only_keyring(prompt::passwd("SMTP password")?) + .await?; + secret + } + Some(sec) if sec == RAW => Secret::new_raw(prompt::passwd("SMTP password")?), + Some(sec) if sec == CMD => Secret::new_command( + Text::new("Shell command") + .with_default(&format!("pass show {account_name}-smtp-passwd")) + .prompt()?, + ), + _ => Default::default(), }; - let port = Text::new("SMTP port") - .with_validators(&[ - Box::new(MinLengthValidator::new(1)), - Box::new(U16Validator {}), - ]) - .with_default(&default_port.to_string()) - .prompt() - .map(|input| input.parse::().unwrap())?; - - let default_login = email.to_owned(); - - let login = Text::new("SMTP login") - .with_default(&default_login) - .prompt()?; - - let oauth2_enabled = Confirm::new("Would you like to enable OAuth 2.0?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); - - let auth = if oauth2_enabled { - let mut config = OAuth2Config::default(); - let redirect_host = OAuth2Config::LOCALHOST.to_owned(); - let redirect_port = OAuth2Config::get_first_available_port()?; - - let method_idx = Select::new("SMTP OAuth 2.0 mechanism", OAUTH2_MECHANISMS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - config.method = match method_idx { - Some(XOAUTH2) => OAuth2Method::XOAuth2, - Some(OAUTHBEARER) => OAuth2Method::OAuthBearer, - _ => OAuth2Method::XOAuth2, - }; - - config.client_id = Text::new("SMTP OAuth 2.0 client id").prompt()?; - - let client_secret: String = Password::new("SMTP OAuth 2.0 client secret") - .with_display_mode(inquire::PasswordDisplayMode::Masked) - .prompt()?; - config.client_secret = - Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-client-secret"))?; - config - .client_secret - .set_only_keyring(&client_secret) - .await?; - - config.auth_url = Text::new("SMTP OAuth 2.0 authorization URL").prompt()?; - - config.token_url = Text::new("SMTP OAuth 2.0 token URL").prompt()?; - - let prompt_scope = |prompt: &str| -> Result> { - Ok(Some(Text::new(prompt).prompt()?.to_owned()).filter(|scope| !scope.is_empty())) - }; - - if let Some(scope) = prompt_scope("SMTP OAuth 2.0 main scope")? { - config.scopes = OAuth2Scopes::Scope(scope); - } - - let confirm_additional_scope = || -> Result { - let confirm = Confirm::new("Would you like to add more SMTP OAuth 2.0 scopes?") - .with_default(false) - .prompt_skippable()? - .unwrap_or_default(); - - Ok(confirm) - }; - - while confirm_additional_scope()? { - let mut scopes = match config.scopes { - OAuth2Scopes::Scope(scope) => vec![scope], - OAuth2Scopes::Scopes(scopes) => scopes, - }; - - if let Some(scope) = prompt_scope("Additional SMTP OAuth 2.0 scope")? { - scopes.push(scope) - } - - config.scopes = OAuth2Scopes::Scopes(scopes); - } - - config.pkce = Confirm::new("Would you like to enable PKCE verification?") - .with_default(true) - .prompt_skippable()? - .unwrap_or(true); - - wizard_log!("To complete your OAuth 2.0 setup, click on the following link:"); - - let client = Client::new( - config.client_id.clone(), - client_secret, - config.auth_url.clone(), - config.token_url.clone(), - )? - .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port) - .build()?; - - let mut auth_code_grant = AuthorizationCodeGrant::new() - .with_redirect_host(redirect_host.to_owned()) - .with_redirect_port(redirect_port); - - if config.pkce { - auth_code_grant = auth_code_grant.with_pkce(); - } - - for scope in config.scopes.clone() { - auth_code_grant = auth_code_grant.with_scope(scope); - } - - let (redirect_url, csrf_token) = auth_code_grant.get_redirect_url(&client); - - println!("{redirect_url}"); - println!(); - - let (access_token, refresh_token) = auth_code_grant - .wait_for_redirection(&client, csrf_token) - .await?; - - config.access_token = - Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-access-token"))?; - config.access_token.set_only_keyring(access_token).await?; - - if let Some(refresh_token) = &refresh_token { - config.refresh_token = - Secret::try_new_keyring_entry(format!("{account_name}-smtp-oauth2-refresh-token"))?; - config.refresh_token.set_only_keyring(refresh_token).await?; - } - - SmtpAuthConfig::OAuth2(config) - } else { - let secret_idx = Select::new("SMTP authentication strategy", SECRETS.to_vec()) - .with_starting_cursor(0) - .prompt_skippable()?; - - let secret = match secret_idx { - Some(KEYRING) => { - let secret = Secret::try_new_keyring_entry(format!("{account_name}-smtp-passwd"))?; - secret - .set_only_keyring(prompt::passwd("SMTP password")?) - .await?; - secret - } - Some(RAW) => Secret::new_raw(prompt::passwd("SMTP password")?), - Some(CMD) => Secret::new_command( - Text::new("Shell command") - .with_default(&format!("pass show {account_name}-smtp-passwd")) - .prompt()?, - ), - _ => Default::default(), - }; - - SmtpAuthConfig::Passwd(PasswdConfig(secret)) - }; - - let config = SmtpConfig { - host, - port, - encryption, - login, - auth, - }; - - Ok(BackendConfig::Smtp(config)) + Ok(SmtpAuthConfig::Passwd(PasswdConfig(secret))) } diff --git a/src/ui/prompt.rs b/src/ui/prompt.rs index 811469d..e4b67cb 100644 --- a/src/ui/prompt.rs +++ b/src/ui/prompt.rs @@ -14,6 +14,7 @@ pub(crate) fn passwd(prompt: &str) -> io::Result { }) } +#[cfg(feature = "oauth2")] pub(crate) fn secret(prompt: &str) -> io::Result { inquire::Password::new(prompt) .with_display_mode(inquire::PasswordDisplayMode::Masked)