diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ea49ee..31d9bd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,20 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.9.0] - 2023-08-28 + ### Added - Added 3 new cargo features: - - `cmds-pgp`: enables the commands PGP backend (enabled by default, same behaviour as before) - - `gpg`: enables the GPG backend (requires the `gpgme` lib on the system) - - `native-pgp`: enables the native PGP backend + - `pgp-commands`: enables the commands PGP backend (enabled by default, same behaviour as before) + - `pgp-gpg`: enables the GPG backend (requires the `gpgme` lib on the system) + - `pgp-native`: enables the native PGP backend - Added account configuration `pgp` to configure the way PGP operations are performed. -### Removed +### Changed -- Removed account configuration `email-writing-encrypt-cmd`. -- Removed account configuration `email-reading-decrypt-cmd`. -- Removed account configuration `email-writing-sign-cmd`. -- Removed account configuration `email-reading-verify-cmd`. +- Moved `email-writing-encrypt-cmd`to `pgp.encrypt-cmd`. +- Moved `email-reading-decrypt-cmd` to `pgp-decrypt-cmd`. +- Moved `email-writing-sign-cmd` to `pgp.sign-cmd`. +- Moved `email-reading-verify-cmd` to `pgp.verify-cmd`. ## [0.8.4] - 2023-07-18 @@ -603,7 +605,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Password from command [#22] - Set up README [#20] -[Unreleased]: https://github.com/soywod/himalaya/compare/v0.8.4...HEAD +[Unreleased]: https://github.com/soywod/himalaya/compare/v0.9.0...HEAD +[0.9.0]: https://github.com/soywod/himalaya/compare/v0.8.4...v0.9.0 [0.8.4]: https://github.com/soywod/himalaya/compare/v0.8.3...v0.8.4 [0.8.3]: https://github.com/soywod/himalaya/compare/v0.8.2...v0.8.3 [0.8.2]: https://github.com/soywod/himalaya/compare/v0.8.1...v0.8.2 diff --git a/Cargo.lock b/Cargo.lock index b1d6033..25ebc0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -997,6 +997,54 @@ dependencies = [ "zeroize", ] +[[package]] +name = "email-lib" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b24c6a2ef2ffbfe518b531ee5cc252ed6014e3cbfe1734e7cece299dbd12eb1b" +dependencies = [ + "advisory-lock", + "ammonia", + "async-trait", + "chrono", + "convert_case", + "dirs", + "futures", + "html-escape", + "imap", + "imap-proto", + "keyring-lib", + "log", + "mail-builder", + "mail-parser", + "mail-send", + "maildirpp", + "md5", + "mml-lib", + "notmuch", + "oauth-lib", + "once_cell", + "ouroboros", + "pgp-lib", + "process-lib", + "rayon", + "regex", + "rfc2047-decoder", + "rusqlite", + "rustls 0.21.1", + "rustls-native-certs", + "secret-lib", + "shellexpand", + "thiserror", + "tokio", + "tokio-rustls 0.24.0", + "tree_magic", + "urlencoding", + "utf7-imap", + "uuid", + "webpki-roots 0.22.6", +] + [[package]] name = "email_address" version = "0.2.4" @@ -1430,7 +1478,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "himalaya" -version = "0.9.0-beta" +version = "0.9.0" dependencies = [ "anyhow", "async-trait", @@ -1443,19 +1491,20 @@ dependencies = [ "coredump", "dialoguer", "dirs", + "email-lib", "email_address", "env_logger", "erased-serde", "indicatif", + "keyring-lib", "log", "md5", + "mml-lib", + "oauth-lib", "once_cell", - "pimalaya-email", - "pimalaya-keyring", - "pimalaya-oauth2", - "pimalaya-process", - "pimalaya-secret", + "process-lib", "rusqlite", + "secret-lib", "serde", "serde_json", "shellexpand", @@ -1827,6 +1876,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "keyring-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dcc9433b6eaf33f2f6a8d3a53b598a5d0b8be224c41bd98d1ec936ef4d02d69" +dependencies = [ + "keyring", + "log", + "thiserror", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2117,6 +2177,28 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "mml-lib" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87247d31f8b76ac7e5d2e23395a83f54978a8716318db6e66a026f50f9288e3" +dependencies = [ + "async-recursion", + "chumsky 0.9.0", + "gpgme", + "keyring-lib", + "log", + "mail-builder", + "mail-parser", + "nanohtml2text", + "pgp-lib", + "process-lib", + "secret-lib", + "shellexpand", + "thiserror", + "tree_magic", +] + [[package]] name = "nanohtml2text" version = "0.1.4" @@ -2234,6 +2316,20 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "oauth-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1484d9864dbf6b55b3785380631a253fa0ff7f8e1bbb078bfd7effd11283d61" +dependencies = [ + "log", + "oauth2", + "reqwest", + "thiserror", + "tokio", + "url", +] + [[package]] name = "oauth2" version = "4.3.0" @@ -2465,6 +2561,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "pgp-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d61233a437ba3de6396593cb27fda4e48ba7c7415756caffe9f9d5d0d07378c" +dependencies = [ + "async-recursion", + "futures", + "hyper", + "hyper-rustls 0.24.1", + "log", + "pgp", + "rand", + "sha1", + "smallvec", + "thiserror", + "tokio", + "url", + "z-base-32", +] + [[package]] name = "phf" version = "0.10.1" @@ -2503,138 +2620,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pimalaya-email" -version = "0.14.1-beta" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "advisory-lock", - "ammonia", - "async-trait", - "chrono", - "convert_case", - "dirs", - "futures", - "html-escape", - "imap", - "imap-proto", - "log", - "mail-builder", - "mail-parser", - "mail-send", - "maildirpp", - "md5", - "notmuch", - "once_cell", - "ouroboros", - "pimalaya-email-tpl", - "pimalaya-keyring", - "pimalaya-oauth2", - "pimalaya-pgp", - "pimalaya-process", - "pimalaya-secret", - "rayon", - "regex", - "rfc2047-decoder", - "rusqlite", - "rustls 0.21.1", - "rustls-native-certs", - "shellexpand", - "thiserror", - "tokio", - "tokio-rustls 0.24.0", - "tree_magic", - "urlencoding", - "utf7-imap", - "uuid", - "webpki-roots 0.22.6", -] - -[[package]] -name = "pimalaya-email-tpl" -version = "0.3.2-beta" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "async-recursion", - "chumsky 0.9.0", - "gpgme", - "log", - "mail-builder", - "mail-parser", - "nanohtml2text", - "pimalaya-keyring", - "pimalaya-pgp", - "pimalaya-process", - "pimalaya-secret", - "shellexpand", - "thiserror", - "tree_magic", -] - -[[package]] -name = "pimalaya-keyring" -version = "0.0.6-beta" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "keyring", - "log", - "thiserror", -] - -[[package]] -name = "pimalaya-oauth2" -version = "0.0.5-beta" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "log", - "oauth2", - "reqwest", - "thiserror", - "tokio", - "url", -] - -[[package]] -name = "pimalaya-pgp" -version = "0.0.1" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "async-recursion", - "futures", - "hyper", - "hyper-rustls 0.24.1", - "log", - "pgp", - "rand", - "sha1", - "smallvec", - "thiserror", - "tokio", - "url", - "z-base-32", -] - -[[package]] -name = "pimalaya-process" -version = "0.0.6-beta" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "log", - "thiserror", - "tokio", -] - -[[package]] -name = "pimalaya-secret" -version = "0.0.6-beta" -source = "git+https://git.sr.ht/~soywod/pimalaya#b75297ae474a231eb13c9bd7c04b5dc877026948" -dependencies = [ - "log", - "pimalaya-keyring", - "pimalaya-process", - "thiserror", -] - [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2746,6 +2731,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "process-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe824234b824573ff3a80ddf3a6b19e6ffba966798d071f280723ee02a7273ce" +dependencies = [ + "log", + "thiserror", + "tokio", +] + [[package]] name = "psm" version = "0.1.21" @@ -3184,6 +3180,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secret-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d46e99ae858a1978ec3e6e887966514900229fc0df99935a2c61102854f9195e" +dependencies = [ + "keyring-lib", + "log", + "process-lib", + "thiserror", +] + [[package]] name = "security-framework" version = "2.7.0" diff --git a/Cargo.toml b/Cargo.toml index 15c62ad..1045b96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,74 +1,149 @@ [package] name = "himalaya" -description = "CLI to manage your emails." -version = "0.9.0-beta" +description = "CLI to manage emails." +version = "0.9.0" authors = ["soywod "] edition = "2021" license = "MIT" categories = ["command-line-interface", "command-line-utilities", "email"] keywords = ["cli", "mail", "email", "client", "imap"] -homepage = "https://pimalaya.org/himalaya/" +homepage = "https://pimalaya.org/" documentation = "https://pimalaya.org/himalaya/" -repository = "https://github.com/soywod/himalaya" - -[package.metadata.docs.rs] -all-features = true +repository = "https://github.com/soywod/himalaya/" +metadata.docs.rs.all-features = true [features] -default = ["imap-backend", "smtp-sender", "cmds-pgp"] +default = ["imap-backend", "smtp-sender", "pgp-commands"] # backends -imap-backend = ["pimalaya-email/imap-backend"] -notmuch-backend = ["pimalaya-email/notmuch-backend"] -cmds-pgp = ["pimalaya-email/cmds-pgp"] -gpg = ["pimalaya-email/gpg"] -native-pgp = ["pimalaya-email/native-pgp"] +imap-backend = ["email-lib/imap-backend"] +notmuch-backend = ["email-lib/notmuch-backend"] # senders -smtp-sender = ["pimalaya-email/smtp-sender"] +smtp-sender = ["email-lib/smtp-sender"] -[dev-dependencies] -async-trait = "0.1" -tempfile = "3.3" +# pgp +pgp-commands = ["email-lib/pgp-commands"] +pgp-gpg = ["email-lib/pgp-gpg"] +pgp-native = ["email-lib/pgp-native"] -[dependencies] -anyhow = "1.0" -atty = "0.2" -chrono = "0.4.24" -clap = "4.0" -clap_complete = "4.0" -clap_mangen = "0.2" -console = "0.15.2" -dialoguer = "0.10.2" -dirs = "4.0.0" -email_address = "0.2.4" -env_logger = "0.8" -erased-serde = "0.3" -indicatif = "0.17" -log = "0.4" -md5 = "0.7.0" -once_cell = "1.16.0" -pimalaya-email = { git = "https://git.sr.ht/~soywod/pimalaya", default-features = false } -pimalaya-keyring = { git = "https://git.sr.ht/~soywod/pimalaya" } -pimalaya-oauth2 = { git = "https://git.sr.ht/~soywod/pimalaya" } -pimalaya-process = { git = "https://git.sr.ht/~soywod/pimalaya" } -pimalaya-secret = { git = "https://git.sr.ht/~soywod/pimalaya" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -shellexpand = "2.1" -termcolor = "1.1" -terminal_size = "0.1" -tokio = { version = "1.23", default-features = false, features = ["macros", "rt-multi-thread"] } -toml = "0.7.4" -toml_edit = "0.19.8" -unicode-width = "0.1" -url = "2.2" -uuid = { version = "0.8", features = ["v4"] } +[dev-dependencies.async-trait] +version = "0.1" -[target.'cfg(target_env = "musl")'.dependencies] -rusqlite = { version = "0.29", features = [] } -[target.'cfg(not(target_env = "musl"))'.dependencies] -rusqlite = { version = "0.29", features = ["bundled"] } +[dev-dependencies.tempfile] +version = "3.3" -[target.'cfg(not(windows))'.dependencies] -coredump = "=0.1.2" +[dependencies.anyhow] +version = "1.0" + +[dependencies.atty] +version = "0.2" + +[dependencies.chrono] +version = "0.4.24" + +[dependencies.clap] +version = "4.0" + +[dependencies.clap_complete] +version = "4.0" + +[dependencies.clap_mangen] +version = "0.2" + +[dependencies.console] +version = "0.15.2" + +[dependencies.dialoguer] +version = "0.10.2" + +[dependencies.dirs] +version = "4.0.0" + +[dependencies.email_address] +version = "0.2.4" + +[dependencies.env_logger] +version = "0.8" + +[dependencies.erased-serde] +version = "0.3" + +[dependencies.indicatif] +version = "0.17" + +[dependencies.log] +version = "0.4" + +[dependencies.md5] +version = "0.7.0" + +[dependencies.once_cell] +version = "1.16.0" + +[dependencies.email-lib] +version = "=0.15.0" +default-features = false + +[dependencies.keyring-lib] +version = "=0.1.0" + +[dependencies.oauth-lib] +version = "=0.1.0" + +[dependencies.process-lib] +version = "=0.1.0" + +[dependencies.mml-lib] +version = "=0.2.1" + +[dependencies.secret-lib] +version = "=0.1.0" + +[dependencies.serde] +version = "1.0" +features = ["derive"] + +[dependencies.serde_json] +version = "1.0" + +[dependencies.shellexpand] +version = "2.1" + +[dependencies.termcolor] +version = "1.1" + +[dependencies.terminal_size] +version = "0.1" + +[dependencies.tokio] +version = "1.23" +default-features = false +features = ["macros", "rt-multi-thread"] + +[dependencies.toml] +version = "0.7.4" + +[dependencies.toml_edit] +version = "0.19.8" + +[dependencies.unicode-width] +version = "0.1" + +[dependencies.url] +version = "2.2" + +[dependencies.uuid] +version = "0.8" +features = ["v4"] + +[target.'cfg(target_env = "musl")'.dependencies.rusqlite] +version = "0.29" +features = [] + +[target.'cfg(not(target_env = "musl"))'.dependencies.rusqlite] +version = "0.29" +features = ["bundled"] + +[target.'cfg(not(windows))'.dependencies.coredump] +version = "=0.1.2" diff --git a/README.md b/README.md index 7f20243..66d900e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ https://pimalaya.org/himalaya/ -CLI to manage your emails, based on the [pimalaya-email](https://sr.ht/~soywod/pimalaya/) library. +CLI to manage emails, based on [email-lib](https://sr.ht/~soywod/pimalaya/). ![image](https://user-images.githubusercontent.com/10437171/138774902-7b9de5a3-93eb-44b0-8cfb-6d2e11e3b1aa.png) @@ -99,16 +99,15 @@ If you want to **discuss** about the project, feel free to join the [Matrix](htt Special thanks to the [nlnet](https://nlnet.nl/project/Himalaya/index.html) foundation that helped Himalaya to receive financial support from the [NGI Assure](https://www.ngi.eu/ngi-projects/ngi-assure/) program of the European Commission in September, 2022. -* [himalaya-lib](https://git.sr.ht/~soywod/himalaya-lib) -* [IMAP RFC3501](https://tools.ietf.org/html/rfc3501) -* [Iris](https://github.com/soywod/iris.vim), the himalaya predecessor -* [isync](https://isync.sourceforge.io/), an email synchronizer for offline usage -* [NeoMutt](https://neomutt.org/), an email terminal user interface -* [Alpine](http://alpine.x10host.com/alpine/alpine-info/), an other email terminal user interface -* [mutt-wizard](https://github.com/LukeSmithxyz/mutt-wizard), a tool over NeoMutt and isync -* [rust-imap](https://github.com/jonhoo/rust-imap), a Rust IMAP library -* [lettre](https://github.com/lettre/lettre), a Rust mailer library -* [mailparse](https://github.com/staktrace/mailparse), a Rust MIME email parser. +- [IMAP RFC3501](https://tools.ietf.org/html/rfc3501) +- [Iris](https://github.com/soywod/iris.vim), the himalaya predecessor +- [isync](https://isync.sourceforge.io/), an email synchronizer for offline usage +- [NeoMutt](https://neomutt.org/), an email terminal user interface +- [Alpine](http://alpine.x10host.com/alpine/alpine-info/), an other email terminal user interface +- [mutt-wizard](https://github.com/LukeSmithxyz/mutt-wizard), a tool over NeoMutt and isync +- [rust-imap](https://github.com/jonhoo/rust-imap), a Rust IMAP library +- [lettre](https://github.com/lettre/lettre), a Rust mailer library +- [mailparse](https://github.com/staktrace/mailparse), a Rust MIME email parser. ## Sponsoring diff --git a/flake.lock b/flake.lock index b7bca61..2c6a5fd 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1686032467, - "narHash": "sha256-KUCS237H0G1QGx5ehhEmh5yKtcDGCxvVXVtz8xEDAKE=", + "lastModified": 1693117181, + "narHash": "sha256-LC4MUYim2zsYfuUOXcaSDIFHwzIcHbDmzDTBh5FXDBA=", "owner": "nix-community", "repo": "fenix", - "rev": "1a3e0f661119a7435099b118912d65bdbbf3bb11", + "rev": "8d8f72faedbf61b0f16b9d87c8f79076d7570202", "type": "github" }, "original": { @@ -42,11 +42,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1692799911, + "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", "type": "github" }, "original": { @@ -82,11 +82,11 @@ ] }, "locked": { - "lastModified": 1679567394, - "narHash": "sha256-ZvLuzPeARDLiQUt6zSZFGOs+HZmE+3g4QURc8mkBsfM=", + "lastModified": 1692351612, + "narHash": "sha256-KTGonidcdaLadRnv9KFgwSMh1ZbXoR/OBmPjeNMhFwU=", "owner": "nix-community", "repo": "naersk", - "rev": "88cd22380154a2c36799fe8098888f0f59861a15", + "rev": "78789c30d64dea2396c9da516bbcc8db3a475207", "type": "github" }, "original": { @@ -97,16 +97,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1685883127, - "narHash": "sha256-zPDaPNrAtBnO24rNqjHLINHsqTdRbgWy1c/TL3EdwlM=", + "lastModified": 1693087214, + "narHash": "sha256-Kn1SSqRfPpqcI1MDy82JXrPT1WI8c03TA2F0xu6kS+4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d4a9ff82fc18723219b60c66fb2ccb0734c460eb", + "rev": "f155f0cf4ea43c4e3c8918d2d327d44777b6cad4", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-22.11", + "ref": "nixos-23.05", "repo": "nixpkgs", "type": "github" } @@ -124,11 +124,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1685984106, - "narHash": "sha256-dOEuU1AuASOWdXT/SbVpD8uX7JjiW3lCp08SbviHuww=", + "lastModified": 1692775770, + "narHash": "sha256-LwoR5N1JHykSte2Ak+Pj/HjJ9fKy9zMJNEftfBJQkLs=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "d42d55feaafa71e14521bbfe6e7011fbb41980f0", + "rev": "f5b7c60ff7a79bfb3e10f3e98c81b7bb4cb53c68", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 7a1ac52..8c85094 100644 --- a/flake.nix +++ b/flake.nix @@ -1,8 +1,8 @@ { - description = "CLI to manage your emails."; + description = "CLI to manage emails."; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05"; flake-utils.url = "github:numtide/flake-utils"; gitignore = { url = "github:hercules-ci/gitignore.nix"; @@ -48,6 +48,7 @@ notmuch # gpg + gnupg gpgme ]; }; @@ -95,8 +96,8 @@ SQLITE3_LIB_DIR = "${sqlite.out}/lib"; hardeningDisable = [ "all" ]; }); - # FIXME: package does not build, assembler messages: unknown - # pseudo-op… + # FIXME: bzlip: fatal error: windows.h: No such file or directory + # May be related to SQLite. windows = mkPackageWithTarget "x86_64-pc-windows-gnu" { strictDeps = true; depsBuildBuild = with pkgs.pkgsCross.mingwW64; [ diff --git a/rust-toolchain.nix b/rust-toolchain.nix index 7db4068..291ba33 100644 --- a/rust-toolchain.nix +++ b/rust-toolchain.nix @@ -2,7 +2,7 @@ fenix: let file = ./rust-toolchain.toml; - sha256 = "ks0nMEGGXKrHnfv4Fku+vhQ7gx76ruv6Ij4fKZR3l78="; + sha256 = "Q9UgzzvxLi4x9aWUJTn+/5EXekC98ODRU1TwhUs9RnY="; in { fromFile = { system }: fenix.packages.${system}.fromToolchainFile { diff --git a/src/cache/id_mapper.rs b/src/cache/id_mapper.rs index d93b540..5533a4e 100644 --- a/src/cache/id_mapper.rs +++ b/src/cache/id_mapper.rs @@ -1,13 +1,13 @@ use anyhow::{anyhow, Context, Result}; -use log::{debug, trace}; #[cfg(feature = "imap-backend")] -use pimalaya_email::backend::ImapBackend; +use email::backend::ImapBackend; #[cfg(feature = "notmuch-backend")] -use pimalaya_email::backend::NotmuchBackend; -use pimalaya_email::{ +use email::backend::NotmuchBackend; +use email::{ account::AccountConfig, backend::{Backend, MaildirBackend}, }; +use log::{debug, trace}; use std::path::{Path, PathBuf}; const ID_MAPPER_DB_FILE_NAME: &str = ".id-mapper.sqlite"; diff --git a/src/config/config.rs b/src/config/config.rs index 1adf3fb..b36a9b2 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -6,14 +6,14 @@ use anyhow::{anyhow, Context, Result}; use dialoguer::Confirm; use dirs::{config_dir, home_dir}; -use log::{debug, trace}; -use pimalaya_email::{ +use email::{ account::AccountConfig, email::{EmailHooks, EmailTextPlainFormat}, }; -use pimalaya_process::Cmd; +use log::{debug, trace}; +use process::Cmd; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fs, path::PathBuf, process}; +use std::{collections::HashMap, fs, path::PathBuf, process::exit}; use toml; use crate::{ @@ -101,7 +101,7 @@ impl DeserializedConfig { .interact_opt()? .unwrap_or_default() { - process::exit(0); + exit(0); } wizard::configure().await? @@ -160,19 +160,19 @@ impl DeserializedConfig { #[cfg(test)] mod tests { - use pimalaya_email::{ + use email::{ account::PasswdConfig, backend::{BackendConfig, MaildirConfig}, sender::{SenderConfig, SendmailConfig}, }; - use pimalaya_secret::Secret; + use secret::Secret; #[cfg(feature = "notmuch-backend")] - use pimalaya_email::backend::NotmuchConfig; + use email::backend::NotmuchConfig; #[cfg(feature = "imap-backend")] - use pimalaya_email::backend::{ImapAuthConfig, ImapConfig}; + use email::backend::{ImapAuthConfig, ImapConfig}; #[cfg(feature = "smtp-sender")] - use pimalaya_email::sender::{SmtpAuthConfig, SmtpConfig}; + use email::sender::{SmtpAuthConfig, SmtpConfig}; use std::io::Write; use tempfile::NamedTempFile; @@ -463,17 +463,28 @@ mod tests { ) .await; - assert!(config - .unwrap_err() - .root_cause() - .to_string() - .contains("missing field `sendmail-cmd`")); + assert_eq!( + config.unwrap(), + DeserializedConfig { + accounts: HashMap::from_iter([( + "account".into(), + DeserializedAccountConfig { + email: "test@localhost".into(), + sender: SenderConfig::Sendmail(SendmailConfig { + cmd: "/usr/sbin/sendmail".into() + }), + ..DeserializedAccountConfig::default() + } + )]), + ..DeserializedConfig::default() + } + ) } #[cfg(feature = "smtp-sender")] #[tokio::test] async fn account_smtp_sender_minimum_config() { - use pimalaya_email::sender::SenderConfig; + use email::sender::SenderConfig; let config = make_config( "[account] diff --git a/src/config/prelude.rs b/src/config/prelude.rs index adc192f..492b211 100644 --- a/src/config/prelude.rs +++ b/src/config/prelude.rs @@ -1,25 +1,25 @@ -#[cfg(feature = "cmds-pgp")] -use pimalaya_email::account::CmdsPgpConfig; -#[cfg(feature = "gpg")] -use pimalaya_email::account::GpgConfig; -#[cfg(feature = "native-pgp")] -use pimalaya_email::account::{NativePgpConfig, NativePgpSecretKey, SignedSecretKey}; +#[cfg(feature = "pgp-commands")] +use email::account::CmdsPgpConfig; +#[cfg(feature = "pgp-gpg")] +use email::account::GpgConfig; +#[cfg(feature = "pgp-native")] +use email::account::{NativePgpConfig, NativePgpSecretKey, SignedSecretKey}; #[cfg(feature = "notmuch-backend")] -use pimalaya_email::backend::NotmuchConfig; +use email::backend::NotmuchConfig; #[cfg(feature = "imap-backend")] -use pimalaya_email::backend::{ImapAuthConfig, ImapConfig}; +use email::backend::{ImapAuthConfig, ImapConfig}; #[cfg(feature = "smtp-sender")] -use pimalaya_email::sender::{SmtpAuthConfig, SmtpConfig}; -use pimalaya_email::{ +use email::sender::{SmtpAuthConfig, SmtpConfig}; +use email::{ account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig, PgpConfig}, backend::{BackendConfig, MaildirConfig}, email::{EmailHooks, EmailTextPlainFormat}, folder::sync::FolderSyncStrategy, sender::{SenderConfig, SendmailConfig}, }; -use pimalaya_keyring::Entry; -use pimalaya_process::{Cmd, Pipeline, SingleCmd}; -use pimalaya_secret::Secret; +use keyring::Entry; +use process::{Cmd, Pipeline, SingleCmd}; +use secret::Secret; use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer}; use std::{collections::HashSet, ops::Deref, path::PathBuf}; @@ -407,23 +407,23 @@ pub enum FolderSyncStrategyDef { pub enum PgpConfigDef { #[default] None, - #[cfg(feature = "cmds-pgp")] + #[cfg(feature = "pgp-commands")] #[serde(with = "CmdsPgpConfigDef", alias = "commands")] Cmds(CmdsPgpConfig), - #[cfg(feature = "gpg")] + #[cfg(feature = "pgp-gpg")] #[serde(with = "GpgConfigDef")] Gpg(GpgConfig), - #[cfg(feature = "native-pgp")] + #[cfg(feature = "pgp-native")] #[serde(with = "NativePgpConfigDef")] Native(NativePgpConfig), } -#[cfg(feature = "gpg")] +#[cfg(feature = "pgp-gpg")] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] #[serde(remote = "GpgConfig", rename_all = "kebab-case")] pub struct GpgConfigDef; -#[cfg(feature = "cmds-pgp")] +#[cfg(feature = "pgp-commands")] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] #[serde(remote = "CmdsPgpConfig", rename_all = "kebab-case")] pub struct CmdsPgpConfigDef { @@ -441,7 +441,7 @@ pub struct CmdsPgpConfigDef { verify_cmd: Option, } -#[cfg(feature = "native-pgp")] +#[cfg(feature = "pgp-native")] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] #[serde(remote = "NativePgpConfig", rename_all = "kebab-case")] pub struct NativePgpConfigDef { @@ -455,7 +455,7 @@ pub struct NativePgpConfigDef { key_servers: Vec, } -#[cfg(feature = "native-pgp")] +#[cfg(feature = "pgp-native")] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] #[serde(remote = "NativePgpSecretKey", rename_all = "kebab-case")] pub enum NativePgpSecretKeyDef { diff --git a/src/domain/account/accounts.rs b/src/domain/account/accounts.rs index 4da4d6e..d752e00 100644 --- a/src/domain/account/accounts.rs +++ b/src/domain/account/accounts.rs @@ -5,7 +5,7 @@ //! accounts from the config file. use anyhow::Result; -use pimalaya_email::backend::BackendConfig; +use email::backend::BackendConfig; use serde::Serialize; use std::{collections::hash_map::Iter, ops::Deref}; diff --git a/src/domain/account/args.rs b/src/domain/account/args.rs index b043df9..ee3c43b 100644 --- a/src/domain/account/args.rs +++ b/src/domain/account/args.rs @@ -2,8 +2,8 @@ use anyhow::Result; use clap::{Arg, ArgAction, ArgMatches, Command}; +use email::folder::sync::FolderSyncStrategy; use log::info; -use pimalaya_email::folder::sync::FolderSyncStrategy; use std::collections::HashSet; use crate::{folder, ui::table}; diff --git a/src/domain/account/config.rs b/src/domain/account/config.rs index dd3e2f8..4b1a54f 100644 --- a/src/domain/account/config.rs +++ b/src/domain/account/config.rs @@ -4,17 +4,17 @@ //! account in the accounts section of the user configuration file. #[cfg(feature = "imap-backend")] -use pimalaya_email::backend::ImapAuthConfig; +use email::backend::ImapAuthConfig; #[cfg(feature = "smtp-sender")] -use pimalaya_email::sender::SmtpAuthConfig; -use pimalaya_email::{ +use email::sender::SmtpAuthConfig; +use email::{ account::{AccountConfig, PgpConfig}, backend::BackendConfig, email::{EmailHooks, EmailTextPlainFormat}, folder::sync::FolderSyncStrategy, sender::SenderConfig, }; -use pimalaya_process::Cmd; +use process::Cmd; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, path::PathBuf}; diff --git a/src/domain/account/handlers.rs b/src/domain/account/handlers.rs index 4319735..ab84df4 100644 --- a/src/domain/account/handlers.rs +++ b/src/domain/account/handlers.rs @@ -3,14 +3,11 @@ //! This module gathers all account actions triggered by the CLI. use anyhow::Result; -use indicatif::{MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; -use log::{info, trace, warn}; -use once_cell::sync::Lazy; #[cfg(feature = "imap-backend")] -use pimalaya_email::backend::ImapAuthConfig; +use email::backend::ImapAuthConfig; #[cfg(feature = "smtp-sender")] -use pimalaya_email::sender::SmtpAuthConfig; -use pimalaya_email::{ +use email::sender::SmtpAuthConfig; +use email::{ account::{ sync::{AccountSyncBuilder, AccountSyncProgressEvent}, AccountConfig, @@ -18,6 +15,9 @@ use pimalaya_email::{ backend::BackendConfig, sender::SenderConfig, }; +use indicatif::{MultiProgress, ProgressBar, ProgressFinish, ProgressStyle}; +use log::{info, trace, warn}; +use once_cell::sync::Lazy; use std::{collections::HashMap, sync::Mutex}; use crate::{ @@ -294,7 +294,7 @@ pub async fn sync( #[cfg(test)] mod tests { - use pimalaya_email::{account::AccountConfig, backend::ImapConfig}; + use email::{account::AccountConfig, backend::ImapConfig}; use std::{collections::HashMap, fmt::Debug, io}; use termcolor::ColorSpec; diff --git a/src/domain/backend/imap/handlers.rs b/src/domain/backend/imap/handlers.rs index 7c4ee11..74e85c7 100644 --- a/src/domain/backend/imap/handlers.rs +++ b/src/domain/backend/imap/handlers.rs @@ -3,7 +3,7 @@ //! This module gathers all IMAP handlers triggered by the CLI. use anyhow::Result; -use pimalaya_email::backend::ImapBackend; +use email::backend::ImapBackend; pub async fn notify(imap: &mut ImapBackend, folder: &str, keepalive: u64) -> Result<()> { imap.notify(keepalive, folder).await?; diff --git a/src/domain/backend/imap/wizard.rs b/src/domain/backend/imap/wizard.rs index 884a8f7..1322517 100644 --- a/src/domain/backend/imap/wizard.rs +++ b/src/domain/backend/imap/wizard.rs @@ -1,11 +1,11 @@ use anyhow::Result; use dialoguer::{Confirm, Input, Password, Select}; -use pimalaya_email::{ +use email::{ account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig}, backend::{BackendConfig, ImapAuthConfig, ImapConfig}, }; -use pimalaya_oauth2::{AuthorizationCodeGrant, Client}; -use pimalaya_secret::Secret; +use oauth::v2_0::{AuthorizationCodeGrant, Client}; +use secret::Secret; use crate::{ config::wizard::{prompt_passwd, THEME}, diff --git a/src/domain/backend/maildir/wizard.rs b/src/domain/backend/maildir/wizard.rs index d127ba7..9dd96bb 100644 --- a/src/domain/backend/maildir/wizard.rs +++ b/src/domain/backend/maildir/wizard.rs @@ -1,7 +1,7 @@ use anyhow::Result; use dialoguer::Input; use dirs::home_dir; -use pimalaya_email::backend::{BackendConfig, MaildirConfig}; +use email::backend::{BackendConfig, MaildirConfig}; use crate::config::wizard::THEME; diff --git a/src/domain/backend/notmuch/wizard.rs b/src/domain/backend/notmuch/wizard.rs index a2a783a..8eb87e9 100644 --- a/src/domain/backend/notmuch/wizard.rs +++ b/src/domain/backend/notmuch/wizard.rs @@ -1,6 +1,6 @@ use anyhow::Result; use dialoguer::Input; -use pimalaya_email::backend::{BackendConfig, NotmuchBackend, NotmuchConfig}; +use email::backend::{BackendConfig, NotmuchBackend, NotmuchConfig}; use crate::config::wizard::THEME; diff --git a/src/domain/backend/wizard.rs b/src/domain/backend/wizard.rs index df89fa7..47e84fe 100644 --- a/src/domain/backend/wizard.rs +++ b/src/domain/backend/wizard.rs @@ -1,6 +1,6 @@ use anyhow::Result; use dialoguer::Select; -use pimalaya_email::backend::BackendConfig; +use email::backend::BackendConfig; use crate::config::wizard::THEME; diff --git a/src/domain/email/handlers.rs b/src/domain/email/handlers.rs index ba43d6e..8d5bd51 100644 --- a/src/domain/email/handlers.rs +++ b/src/domain/email/handlers.rs @@ -1,12 +1,12 @@ use anyhow::{anyhow, Context, Result}; use atty::Stream; -use log::{debug, trace}; -use pimalaya_email::{ +use email::{ account::AccountConfig, backend::Backend, email::{template::FilterParts, Flag, Flags, Message, MessageBuilder}, sender::Sender, }; +use log::{debug, trace}; use std::{ fs, io::{self, BufRead}, @@ -127,7 +127,7 @@ pub async fn forward( .with_some_body(body) .build() .await?; - trace!("initial template: {}", *tpl); + trace!("initial template: {tpl}"); editor::edit_tpl_with_editor(config, printer, backend, sender, tpl).await?; Ok(()) } @@ -276,7 +276,7 @@ pub async fn reply( .with_reply_all(all) .build() .await?; - trace!("initial template: {}", *tpl); + trace!("initial template: {tpl}"); editor::edit_tpl_with_editor(config, printer, backend, sender, tpl).await?; backend .add_flags(&folder, vec![id], &Flags::from_iter([Flag::Answered])) @@ -414,7 +414,7 @@ pub async fn write( .with_some_body(body) .build() .await?; - trace!("initial template: {}", *tpl); + trace!("initial template: {tpl}"); editor::edit_tpl_with_editor(config, printer, backend, sender, tpl).await?; Ok(()) } diff --git a/src/domain/envelope/envelopes.rs b/src/domain/envelope/envelopes.rs index cc4b031..9da59c8 100644 --- a/src/domain/envelope/envelopes.rs +++ b/src/domain/envelope/envelopes.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use pimalaya_email::account::AccountConfig; +use email::account::AccountConfig; use serde::Serialize; use std::ops; @@ -17,7 +17,7 @@ impl Envelopes { pub fn from_backend( config: &AccountConfig, id_mapper: &IdMapper, - envelopes: pimalaya_email::email::Envelopes, + envelopes: email::email::Envelopes, ) -> Result { let envelopes = envelopes .iter() @@ -59,7 +59,7 @@ impl PrintTable for Envelopes { #[cfg(test)] mod tests { use chrono::DateTime; - use pimalaya_email::account::AccountConfig; + use email::account::AccountConfig; use std::env; use crate::{Envelopes, IdMapper}; @@ -69,11 +69,10 @@ mod tests { let config = AccountConfig::default(); let id_mapper = IdMapper::Dummy; - let envelopes = - pimalaya_email::email::Envelopes::from_iter([pimalaya_email::email::Envelope { - date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), - ..Default::default() - }]); + let envelopes = email::email::Envelopes::from_iter([email::email::Envelope { + date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), + ..Default::default() + }]); let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap(); let expected_date = "2023-06-15 09:42+04:00"; @@ -90,11 +89,10 @@ mod tests { ..AccountConfig::default() }; - let envelopes = - pimalaya_email::email::Envelopes::from_iter([pimalaya_email::email::Envelope { - date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), - ..Default::default() - }]); + let envelopes = email::email::Envelopes::from_iter([email::email::Envelope { + date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), + ..Default::default() + }]); let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap(); let expected_date = "15/06/2023 09h42"; @@ -114,11 +112,10 @@ mod tests { ..AccountConfig::default() }; - let envelopes = - pimalaya_email::email::Envelopes::from_iter([pimalaya_email::email::Envelope { - date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), - ..Default::default() - }]); + let envelopes = email::email::Envelopes::from_iter([email::email::Envelope { + date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(), + ..Default::default() + }]); let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap(); let expected_date = "15/06/2023 05h42"; diff --git a/src/domain/flag/args.rs b/src/domain/flag/args.rs index 56cfd48..b365f13 100644 --- a/src/domain/flag/args.rs +++ b/src/domain/flag/args.rs @@ -3,10 +3,10 @@ //! This module contains the command matcher, the subcommands and the //! arguments related to the email flag domain. +use ::email::email::{Flag, Flags}; use anyhow::Result; use clap::{Arg, ArgMatches, Command}; use log::{debug, info}; -use pimalaya_email::email::{Flag, Flags}; use crate::email; diff --git a/src/domain/flag/flag.rs b/src/domain/flag/flag.rs index e326814..e48f0bb 100644 --- a/src/domain/flag/flag.rs +++ b/src/domain/flag/flag.rs @@ -11,9 +11,9 @@ pub enum Flag { Custom(String), } -impl From<&pimalaya_email::email::Flag> for Flag { - fn from(flag: &pimalaya_email::email::Flag) -> Self { - use pimalaya_email::email::Flag::*; +impl From<&email::email::Flag> for Flag { + fn from(flag: &email::email::Flag) -> Self { + use email::email::Flag::*; match flag { Seen => Flag::Seen, Answered => Flag::Answered, diff --git a/src/domain/flag/flags.rs b/src/domain/flag/flags.rs index 55f38a4..bcf9f1f 100644 --- a/src/domain/flag/flags.rs +++ b/src/domain/flag/flags.rs @@ -14,8 +14,8 @@ impl ops::Deref for Flags { } } -impl From for Flags { - fn from(flags: pimalaya_email::email::Flags) -> Self { +impl From for Flags { + fn from(flags: email::email::Flags) -> Self { Flags(flags.iter().map(Flag::from).collect()) } } diff --git a/src/domain/flag/handlers.rs b/src/domain/flag/handlers.rs index 13f53b8..04a5fde 100644 --- a/src/domain/flag/handlers.rs +++ b/src/domain/flag/handlers.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use pimalaya_email::{backend::Backend, email::Flags}; +use email::{backend::Backend, email::Flags}; use crate::{printer::Printer, IdMapper}; diff --git a/src/domain/folder/folder.rs b/src/domain/folder/folder.rs index 4b49bbc..7d1e410 100644 --- a/src/domain/folder/folder.rs +++ b/src/domain/folder/folder.rs @@ -8,8 +8,8 @@ pub struct Folder { pub desc: String, } -impl From<&pimalaya_email::folder::Folder> for Folder { - fn from(folder: &pimalaya_email::folder::Folder) -> Self { +impl From<&email::folder::Folder> for Folder { + fn from(folder: &email::folder::Folder) -> Self { Folder { name: folder.name.clone(), desc: folder.desc.clone(), diff --git a/src/domain/folder/folders.rs b/src/domain/folder/folders.rs index d53e37c..dd5cc1d 100644 --- a/src/domain/folder/folders.rs +++ b/src/domain/folder/folders.rs @@ -19,8 +19,8 @@ impl ops::Deref for Folders { } } -impl From for Folders { - fn from(folders: pimalaya_email::folder::Folders) -> Self { +impl From for Folders { + fn from(folders: email::folder::Folders) -> Self { Folders(folders.iter().map(Folder::from).collect()) } } diff --git a/src/domain/folder/handlers.rs b/src/domain/folder/handlers.rs index 7a76cfb..5664e07 100644 --- a/src/domain/folder/handlers.rs +++ b/src/domain/folder/handlers.rs @@ -4,7 +4,7 @@ use anyhow::Result; use dialoguer::Confirm; -use pimalaya_email::{account::AccountConfig, backend::Backend}; +use email::{account::AccountConfig, backend::Backend}; use std::process; use crate::{ @@ -68,7 +68,7 @@ pub async fn delete( #[cfg(test)] mod tests { use async_trait::async_trait; - use pimalaya_email::{ + use email::{ account::AccountConfig, backend::Backend, email::{Envelope, Envelopes, Flags, Messages}, @@ -152,10 +152,10 @@ mod tests { fn name(&self) -> String { unimplemented!(); } - async fn add_folder(&mut self, _: &str) -> pimalaya_email::Result<()> { + async fn add_folder(&mut self, _: &str) -> email::Result<()> { unimplemented!(); } - async fn list_folders(&mut self) -> pimalaya_email::Result { + async fn list_folders(&mut self) -> email::Result { Ok(Folders::from_iter([ Folder { name: "INBOX".into(), @@ -167,16 +167,16 @@ mod tests { }, ])) } - async fn expunge_folder(&mut self, _: &str) -> pimalaya_email::Result<()> { + async fn expunge_folder(&mut self, _: &str) -> email::Result<()> { unimplemented!(); } - async fn purge_folder(&mut self, _: &str) -> pimalaya_email::Result<()> { + async fn purge_folder(&mut self, _: &str) -> email::Result<()> { unimplemented!(); } - async fn delete_folder(&mut self, _: &str) -> pimalaya_email::Result<()> { + async fn delete_folder(&mut self, _: &str) -> email::Result<()> { unimplemented!(); } - async fn get_envelope(&mut self, _: &str, _: &str) -> pimalaya_email::Result { + async fn get_envelope(&mut self, _: &str, _: &str) -> email::Result { unimplemented!(); } async fn list_envelopes( @@ -184,7 +184,7 @@ mod tests { _: &str, _: usize, _: usize, - ) -> pimalaya_email::Result { + ) -> email::Result { unimplemented!() } async fn search_envelopes( @@ -194,64 +194,31 @@ mod tests { _: &str, _: usize, _: usize, - ) -> pimalaya_email::Result { + ) -> email::Result { unimplemented!() } - async fn add_email( - &mut self, - _: &str, - _: &[u8], - _: &Flags, - ) -> pimalaya_email::Result { + async fn add_email(&mut self, _: &str, _: &[u8], _: &Flags) -> email::Result { unimplemented!() } - async fn get_emails( - &mut self, - _: &str, - _: Vec<&str>, - ) -> pimalaya_email::Result { + async fn get_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result { unimplemented!() } - async fn preview_emails( - &mut self, - _: &str, - _: Vec<&str>, - ) -> pimalaya_email::Result { + async fn preview_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result { unimplemented!() } - async fn copy_emails( - &mut self, - _: &str, - _: &str, - _: Vec<&str>, - ) -> pimalaya_email::Result<()> { + async fn copy_emails(&mut self, _: &str, _: &str, _: Vec<&str>) -> email::Result<()> { unimplemented!() } - async fn move_emails( - &mut self, - _: &str, - _: &str, - _: Vec<&str>, - ) -> pimalaya_email::Result<()> { + async fn move_emails(&mut self, _: &str, _: &str, _: Vec<&str>) -> email::Result<()> { unimplemented!() } - async fn delete_emails(&mut self, _: &str, _: Vec<&str>) -> pimalaya_email::Result<()> { + async fn delete_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result<()> { unimplemented!() } - async fn add_flags( - &mut self, - _: &str, - _: Vec<&str>, - _: &Flags, - ) -> pimalaya_email::Result<()> { + async fn add_flags(&mut self, _: &str, _: Vec<&str>, _: &Flags) -> email::Result<()> { unimplemented!() } - async fn set_flags( - &mut self, - _: &str, - _: Vec<&str>, - _: &Flags, - ) -> pimalaya_email::Result<()> { + async fn set_flags(&mut self, _: &str, _: Vec<&str>, _: &Flags) -> email::Result<()> { unimplemented!() } async fn remove_flags( @@ -259,7 +226,7 @@ mod tests { _: &str, _: Vec<&str>, _: &Flags, - ) -> pimalaya_email::Result<()> { + ) -> email::Result<()> { unimplemented!() } fn as_any(&self) -> &dyn Any { diff --git a/src/domain/sender/sendmail/wizard.rs b/src/domain/sender/sendmail/wizard.rs index 5df724c..0297ea5 100644 --- a/src/domain/sender/sendmail/wizard.rs +++ b/src/domain/sender/sendmail/wizard.rs @@ -1,6 +1,6 @@ use anyhow::Result; use dialoguer::Input; -use pimalaya_email::sender::{SenderConfig, SendmailConfig}; +use email::sender::{SenderConfig, SendmailConfig}; use crate::config::wizard::THEME; diff --git a/src/domain/sender/smtp/wizard.rs b/src/domain/sender/smtp/wizard.rs index 75923ed..423f155 100644 --- a/src/domain/sender/smtp/wizard.rs +++ b/src/domain/sender/smtp/wizard.rs @@ -1,11 +1,11 @@ use anyhow::Result; use dialoguer::{Confirm, Input, Select}; -use pimalaya_email::{ +use email::{ account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig}, sender::{SenderConfig, SmtpAuthConfig, SmtpConfig}, }; -use pimalaya_oauth2::{AuthorizationCodeGrant, Client}; -use pimalaya_secret::Secret; +use oauth::v2_0::{AuthorizationCodeGrant, Client}; +use secret::Secret; use crate::{ config::wizard::{prompt_passwd, THEME}, diff --git a/src/domain/sender/wizard.rs b/src/domain/sender/wizard.rs index decd399..d382df1 100644 --- a/src/domain/sender/wizard.rs +++ b/src/domain/sender/wizard.rs @@ -1,6 +1,6 @@ use anyhow::Result; use dialoguer::Select; -use pimalaya_email::sender::SenderConfig; +use email::sender::SenderConfig; use crate::config::wizard::THEME; diff --git a/src/domain/tpl/handlers.rs b/src/domain/tpl/handlers.rs index f7cfd48..131280c 100644 --- a/src/domain/tpl/handlers.rs +++ b/src/domain/tpl/handlers.rs @@ -1,11 +1,12 @@ use anyhow::{anyhow, Result}; use atty::Stream; -use pimalaya_email::{ +use email::{ account::AccountConfig, backend::Backend, - email::{Flag, Flags, Message, Tpl}, + email::{Flag, Flags, Message}, sender::Sender, }; +use mml::MmlCompiler; use std::io::{stdin, BufRead}; use crate::{printer::Printer, IdMapper}; @@ -76,7 +77,7 @@ pub async fn save( folder: &str, tpl: String, ) -> Result<()> { - let email = Tpl::from(if atty::is(Stream::Stdin) || printer.is_json() { + let mml = if atty::is(Stream::Stdin) || printer.is_json() { tpl.replace("\r", "") } else { stdin() @@ -85,11 +86,13 @@ pub async fn save( .filter_map(Result::ok) .collect::>() .join("\n") - }) - .with_pgp(config.pgp.clone()) - .compile() - .await? - .write_to_vec()?; + }; + + let email = MmlCompiler::new() + .with_pgp(config.pgp.clone()) + .compile(mml) + .await? + .write_to_vec()?; let id = backend.add_email(folder, &email, &Flags::default()).await?; id_mapper.create_alias(id)?; @@ -105,7 +108,8 @@ pub async fn send( tpl: String, ) -> Result<()> { let folder = config.sent_folder_alias()?; - let email = Tpl::from(if atty::is(Stream::Stdin) || printer.is_json() { + + let mml = if atty::is(Stream::Stdin) || printer.is_json() { tpl.replace("\r", "") } else { stdin() @@ -114,11 +118,13 @@ pub async fn send( .filter_map(Result::ok) .collect::>() .join("\n") - }) - .with_pgp(config.pgp.clone()) - .compile() - .await? - .write_to_vec()?; + }; + + let email = MmlCompiler::new() + .with_pgp(config.pgp.clone()) + .compile(mml) + .await? + .write_to_vec()?; sender.send(&email).await?; diff --git a/src/main.rs b/src/main.rs index f91dc1a..5a174dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,13 @@ -use anyhow::{anyhow, Context, Result}; -use clap::Command; -use log::{debug, warn}; #[cfg(feature = "imap-backend")] -use pimalaya_email::backend::ImapBackend; -use pimalaya_email::{ +use ::email::backend::ImapBackend; +use ::email::{ account::{sync::AccountSyncBuilder, DEFAULT_INBOX_FOLDER}, backend::{BackendBuilder, BackendConfig}, sender::SenderBuilder, }; +use anyhow::{anyhow, Context, Result}; +use clap::Command; +use log::{debug, warn}; use std::env; use url::Url; diff --git a/src/printer/print.rs b/src/printer/print.rs index 304e57b..54bbde7 100644 --- a/src/printer/print.rs +++ b/src/printer/print.rs @@ -1,5 +1,4 @@ use anyhow::{Context, Result}; -use pimalaya_email::email::Tpl; use crate::printer::WriteColor; @@ -20,10 +19,3 @@ impl Print for String { Ok(writer.reset()?) } } - -impl Print for Tpl { - fn print(&self, writer: &mut dyn WriteColor) -> Result<()> { - self.as_str().print(writer)?; - Ok(writer.reset()?) - } -} diff --git a/src/printer/print_table.rs b/src/printer/print_table.rs index c5e01dc..7066221 100644 --- a/src/printer/print_table.rs +++ b/src/printer/print_table.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use pimalaya_email::email::EmailTextPlainFormat; +use email::email::EmailTextPlainFormat; use std::io; use termcolor::{self, StandardStream}; diff --git a/src/ui/editor.rs b/src/ui/editor.rs index 67be4c2..89057f5 100644 --- a/src/ui/editor.rs +++ b/src/ui/editor.rs @@ -1,42 +1,45 @@ use anyhow::{Context, Result}; -use log::debug; -use pimalaya_email::{ +use email::{ account::AccountConfig, backend::Backend, - email::{local_draft_path, remove_local_draft, Flag, Flags, Tpl}, + email::{local_draft_path, remove_local_draft, Flag, Flags}, sender::Sender, }; -use std::{env, fs, process::Command}; +use log::debug; +use mml::MmlCompiler; +use process::Cmd; +use std::{env, fs}; use crate::{ printer::Printer, ui::choice::{self, PostEditChoice, PreEditChoice}, }; -pub fn open_with_tpl(tpl: Tpl) -> Result { +pub async fn open_with_tpl(tpl: String) -> Result { let path = local_draft_path(); debug!("create draft"); fs::write(&path, tpl.as_bytes()).context(format!("cannot write local draft at {:?}", path))?; debug!("open editor"); - Command::new(env::var("EDITOR").context(r#"cannot find "$EDITOR" env var"#)?) - .arg(&path) - .status() + let editor = env::var("EDITOR").context("cannot get editor from env var")?; + Cmd::from(format!("{editor} {}", &path.to_string_lossy())) + .run() + .await .context("cannot launch editor")?; debug!("read draft"); let content = fs::read_to_string(&path).context(format!("cannot read local draft at {:?}", path))?; - Ok(Tpl::from(content)) + Ok(content) } -pub fn open_with_local_draft() -> Result { +pub async fn open_with_local_draft() -> Result { let path = local_draft_path(); let content = fs::read_to_string(&path).context(format!("cannot read local draft at {:?}", path))?; - open_with_tpl(Tpl::from(content)) + open_with_tpl(content).await } pub async fn edit_tpl_with_editor( @@ -44,7 +47,7 @@ pub async fn edit_tpl_with_editor( printer: &mut P, backend: &mut dyn Backend, sender: &mut dyn Sender, - mut tpl: Tpl, + mut tpl: String, ) -> Result<()> { let draft = local_draft_path(); if draft.exists() { @@ -52,11 +55,11 @@ pub async fn edit_tpl_with_editor( match choice::pre_edit() { Ok(choice) => match choice { PreEditChoice::Edit => { - tpl = open_with_local_draft()?; + tpl = open_with_local_draft().await?; break; } PreEditChoice::Discard => { - tpl = open_with_tpl(tpl)?; + tpl = open_with_tpl(tpl).await?; break; } PreEditChoice::Quit => return Ok(()), @@ -68,16 +71,16 @@ pub async fn edit_tpl_with_editor( } } } else { - tpl = open_with_tpl(tpl)?; + tpl = open_with_tpl(tpl).await?; } loop { match choice::post_edit() { Ok(PostEditChoice::Send) => { printer.print_log("Sending email…")?; - let email = tpl + let email = MmlCompiler::new() .with_pgp(config.pgp.clone()) - .compile() + .compile(tpl) .await? .write_to_vec()?; sender.send(&email).await?; @@ -93,7 +96,7 @@ pub async fn edit_tpl_with_editor( break; } Ok(PostEditChoice::Edit) => { - tpl = open_with_tpl(tpl)?; + tpl = open_with_tpl(tpl).await?; continue; } Ok(PostEditChoice::LocalDraft) => { @@ -101,9 +104,9 @@ pub async fn edit_tpl_with_editor( break; } Ok(PostEditChoice::RemoteDraft) => { - let email = tpl + let email = MmlCompiler::new() .with_pgp(config.pgp.clone()) - .compile() + .compile(tpl) .await? .write_to_vec()?; backend diff --git a/src/ui/table/table.rs b/src/ui/table/table.rs index 59b4ed6..adbe2ca 100644 --- a/src/ui/table/table.rs +++ b/src/ui/table/table.rs @@ -5,8 +5,8 @@ //! [builder design pattern]: https://refactoring.guru/design-patterns/builder use anyhow::{Context, Result}; +use email::email::EmailTextPlainFormat; use log::trace; -use pimalaya_email::email::EmailTextPlainFormat; use termcolor::{Color, ColorSpec}; use terminal_size::terminal_size; use unicode_width::UnicodeWidthStr; @@ -267,7 +267,7 @@ where #[cfg(test)] mod tests { - use pimalaya_email::email::EmailTextPlainFormat; + use email::email::EmailTextPlainFormat; use std::io; use super::*;