mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-24 20:10:23 +00:00
make use of pimalaya_tui::config::TomlConfig
This commit is contained in:
parent
6f5f943875
commit
b92d7b4a08
46 changed files with 205 additions and 308 deletions
82
Cargo.lock
generated
82
Cargo.lock
generated
|
@ -262,7 +262,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -297,7 +297,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -403,7 +403,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
"which",
|
||||
]
|
||||
|
||||
|
@ -483,7 +483,7 @@ checksum = "e0af050e27e5d57aa14975f97fe47a134c46a390f91819f23a625319a7111bfa"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -692,7 +692,7 @@ dependencies = [
|
|||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -952,7 +952,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1284,7 +1284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0f24a09fd651027f8764f8a12c12358715cb9bab622ab3125ede3dd6ae047c95"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1314,7 +1314,7 @@ dependencies = [
|
|||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1335,7 +1335,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1344,15 +1344,6 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.9"
|
||||
|
@ -1603,7 +1594,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1895,7 +1886,6 @@ dependencies = [
|
|||
"dirs 4.0.0",
|
||||
"email-lib",
|
||||
"email_address",
|
||||
"erased-serde",
|
||||
"mail-builder",
|
||||
"md5",
|
||||
"mml-lib",
|
||||
|
@ -2245,9 +2235,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
|
@ -2574,7 +2564,7 @@ dependencies = [
|
|||
"smtp-proto",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.0",
|
||||
"webpki-roots 0.26.3",
|
||||
"webpki-roots 0.26.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2858,7 +2848,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3201,8 +3191,10 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "pimalaya-tui"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pimalaya/tui#80660dfaf9daafbaa716c711e510bf3cfd04cd69"
|
||||
source = "git+https://github.com/pimalaya/tui#0b2403886edcc57491e56da86537541e9b126cbc"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"color-eyre",
|
||||
"crossterm 0.25.0",
|
||||
"dirs 4.0.0",
|
||||
"email-lib",
|
||||
|
@ -3210,8 +3202,16 @@ dependencies = [
|
|||
"inquire",
|
||||
"oauth-lib",
|
||||
"secret-lib",
|
||||
"serde",
|
||||
"serde-toml-merge",
|
||||
"serde_json",
|
||||
"shellexpand-utils",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"toml_edit 0.22.20",
|
||||
"tracing",
|
||||
"tracing-error",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3231,7 +3231,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3331,7 +3331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3970,7 +3970,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4003,7 +4003,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4249,7 +4249,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4271,9 +4271,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.76"
|
||||
version = "2.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
|
||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4366,7 +4366,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4420,7 +4420,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4548,7 +4548,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4800,7 +4800,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -4834,7 +4834,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -4863,9 +4863,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
|||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.3"
|
||||
version = "0.26.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
|
||||
checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
@ -5242,7 +5242,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5262,7 +5262,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.76",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -59,14 +59,13 @@ crossterm = { version = "0.27", features = ["serde"] }
|
|||
dirs = "4"
|
||||
email-lib = { version = "=0.25.0", default-features = false, features = ["derive", "thread", "tracing"] }
|
||||
email_address = { version = "0.2", optional = true }
|
||||
erased-serde = "0.3"
|
||||
mail-builder = "0.3"
|
||||
md5 = "0.7"
|
||||
mml-lib = { version = "=1.0.14", default-features = false, features = ["derive"] }
|
||||
oauth-lib = { version = "=0.1.1", optional = true }
|
||||
once_cell = "1.16"
|
||||
petgraph = "0.6"
|
||||
pimalaya-tui = { version = "=0.1.0", default-features = false, features = ["email", "path"] }
|
||||
pimalaya-tui = { version = "=0.1.0", default-features = false, features = ["email", "path", "cli", "config", "tracing"] }
|
||||
process-lib = { version = "=0.4.2", features = ["derive"] }
|
||||
secret-lib = { version = "=0.4.6", default-features = false, features = ["command", "derive"], optional = true }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
|
|
@ -4,7 +4,7 @@ use email::backend::context::BackendContextBuilder;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::OptionalAccountNameArg, backend, config::TomlConfig, printer::Printer,
|
||||
account::arg::name::OptionalAccountNameArg, backend, config::Config, printer::Printer,
|
||||
};
|
||||
|
||||
/// Check up the given account.
|
||||
|
@ -19,7 +19,7 @@ pub struct AccountCheckUpCommand {
|
|||
}
|
||||
|
||||
impl AccountCheckUpCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing check up account command");
|
||||
|
||||
let account = self.account.name.as_ref().map(String::as_str);
|
||||
|
|
|
@ -10,7 +10,7 @@ use tracing::info;
|
|||
#[cfg(any(feature = "imap", feature = "smtp"))]
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use crate::{account::arg::name::AccountNameArg, config::TomlConfig, printer::Printer};
|
||||
use crate::{account::arg::name::AccountNameArg, config::Config, printer::Printer};
|
||||
|
||||
/// Configure an account.
|
||||
///
|
||||
|
@ -31,7 +31,7 @@ pub struct AccountConfigureCommand {
|
|||
}
|
||||
|
||||
impl AccountConfigureCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing configure account command");
|
||||
|
||||
let account = &self.account.name;
|
||||
|
|
|
@ -4,7 +4,7 @@ use tracing::info;
|
|||
|
||||
use crate::{
|
||||
account::{Accounts, AccountsTable},
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,7 @@ pub struct AccountListCommand {
|
|||
}
|
||||
|
||||
impl AccountListCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing list accounts command");
|
||||
|
||||
let accounts = Accounts::from(config.accounts.iter());
|
||||
|
|
|
@ -5,7 +5,7 @@ mod list;
|
|||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::{
|
||||
check_up::AccountCheckUpCommand, configure::AccountConfigureCommand, list::AccountListCommand,
|
||||
|
@ -30,7 +30,7 @@ pub enum AccountSubcommand {
|
|||
|
||||
impl AccountSubcommand {
|
||||
#[allow(unused)]
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::CheckUp(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Configure(cmd) => cmd.execute(printer, config).await,
|
||||
|
|
|
@ -32,12 +32,11 @@ pub async fn configure(
|
|||
let config = wizard::maildir::start(account_name)?;
|
||||
Ok(BackendConfig::Maildir(config))
|
||||
}
|
||||
// TODO
|
||||
// #[cfg(feature = "notmuch")]
|
||||
// BackendKind::Notmuch => {
|
||||
// let config = wizard::notmuch::start()?;
|
||||
// Ok(BackendConfig::Notmuch(config))
|
||||
// }
|
||||
#[cfg(feature = "notmuch")]
|
||||
BackendKind::Notmuch => {
|
||||
let config = wizard::notmuch::start()?;
|
||||
Ok(BackendConfig::Notmuch(config))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
16
src/cli.rs
16
src/cli.rs
|
@ -5,7 +5,7 @@ use std::path::PathBuf;
|
|||
use crate::{
|
||||
account::command::AccountSubcommand,
|
||||
completion::command::CompletionGenerateCommand,
|
||||
config::{self, TomlConfig},
|
||||
config::{self, Config},
|
||||
envelope::command::EnvelopeSubcommand,
|
||||
flag::command::FlagSubcommand,
|
||||
folder::command::FolderSubcommand,
|
||||
|
@ -111,31 +111,31 @@ impl HimalayaCommand {
|
|||
pub async fn execute(self, printer: &mut impl Printer, config_paths: &[PathBuf]) -> Result<()> {
|
||||
match self {
|
||||
Self::Account(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Folder(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Envelope(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Flag(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Message(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Attachment(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Template(cmd) => {
|
||||
let config = TomlConfig::from_paths_or_default(config_paths).await?;
|
||||
let config = Config::from_paths_or_default(config_paths).await?;
|
||||
cmd.execute(printer, &config).await
|
||||
}
|
||||
Self::Manual(cmd) => cmd.execute(printer).await,
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
#[cfg(feature = "wizard")]
|
||||
pub mod wizard;
|
||||
|
||||
use std::{collections::HashMap, fs, path::PathBuf, sync::Arc};
|
||||
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
||||
|
||||
use color_eyre::{
|
||||
eyre::{bail, eyre, Context},
|
||||
Result,
|
||||
};
|
||||
use color_eyre::{eyre::eyre, Result};
|
||||
use crossterm::style::Color;
|
||||
use dirs::{config_dir, home_dir};
|
||||
use email::{
|
||||
account::config::AccountConfig, config::Config, envelope::config::EnvelopeConfig,
|
||||
folder::config::FolderConfig, message::config::MessageConfig,
|
||||
account::config::AccountConfig, envelope::config::EnvelopeConfig, folder::config::FolderConfig,
|
||||
message::config::MessageConfig,
|
||||
};
|
||||
#[cfg(feature = "wizard")]
|
||||
use pimalaya_tui::{print, prompt};
|
||||
use pimalaya_tui::config::TomlConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_toml_merge::merge;
|
||||
use shellexpand_utils::{canonicalize, expand};
|
||||
use toml::{self, Value};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::account::config::{ListAccountsTableConfig, TomlAccountConfig};
|
||||
|
||||
/// Represents the user config file.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
pub struct TomlConfig {
|
||||
pub struct Config {
|
||||
#[serde(alias = "name")]
|
||||
pub display_name: Option<String>,
|
||||
pub signature: Option<String>,
|
||||
|
@ -36,83 +28,9 @@ pub struct TomlConfig {
|
|||
pub account: Option<AccountsConfig>,
|
||||
}
|
||||
|
||||
impl TomlConfig {
|
||||
pub fn account_list_table_preset(&self) -> Option<String> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.preset.clone())
|
||||
}
|
||||
|
||||
pub fn account_list_table_name_color(&self) -> Option<Color> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.name_color)
|
||||
}
|
||||
|
||||
pub fn account_list_table_backends_color(&self) -> Option<Color> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.backends_color)
|
||||
}
|
||||
|
||||
pub fn account_list_table_default_color(&self) -> Option<Color> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.default_color)
|
||||
}
|
||||
|
||||
/// Read and parse the TOML configuration at the given paths.
|
||||
///
|
||||
/// Returns an error if a configuration file cannot be read or if
|
||||
/// a content cannot be parsed.
|
||||
fn from_paths(paths: &[PathBuf]) -> Result<Self> {
|
||||
match paths.len() {
|
||||
0 => {
|
||||
// should never happen
|
||||
bail!("cannot read config file from empty paths");
|
||||
}
|
||||
1 => {
|
||||
let path = &paths[0];
|
||||
|
||||
let content = &(fs::read_to_string(path)
|
||||
.context(format!("cannot read config file at {path:?}"))?);
|
||||
|
||||
toml::from_str(content).context(format!("cannot parse config file at {path:?}"))
|
||||
}
|
||||
_ => {
|
||||
let path = &paths[0];
|
||||
|
||||
let mut merged_content = fs::read_to_string(path)
|
||||
.context(format!("cannot read config file at {path:?}"))?
|
||||
.parse::<Value>()?;
|
||||
|
||||
for path in &paths[1..] {
|
||||
match fs::read_to_string(path) {
|
||||
Ok(content) => {
|
||||
merged_content = merge(merged_content, content.parse()?).unwrap();
|
||||
}
|
||||
Err(err) => {
|
||||
debug!("skipping subconfig file at {path:?}: {err}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
merged_content
|
||||
.try_into()
|
||||
.context(format!("cannot parse merged config file at {path:?}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl TomlConfig<AccountConfig> for Config {}
|
||||
|
||||
impl Config {
|
||||
/// Create and save a TOML configuration using the wizard.
|
||||
///
|
||||
/// If the user accepts the confirmation, the wizard starts and
|
||||
|
@ -122,25 +40,18 @@ impl TomlConfig {
|
|||
/// NOTE: the wizard can only be used with interactive shells.
|
||||
#[cfg(feature = "wizard")]
|
||||
async fn from_wizard(path: &PathBuf) -> Result<Self> {
|
||||
print::warn(format!("Cannot find existing configuration at {path:?}."));
|
||||
|
||||
if !prompt::bool("Would you like to create one with the wizard? ", true)? {
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
return wizard::configure(path).await;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wizard"))]
|
||||
async fn from_wizard(path: &PathBuf) -> Result<Self> {
|
||||
bail!("Cannot find existing configuration at {path:?}.");
|
||||
Self::confirm_from_wizard(path)?;
|
||||
wizard::configure(path).await
|
||||
}
|
||||
|
||||
/// Read and parse the TOML configuration from default paths.
|
||||
pub async fn from_default_paths() -> Result<Self> {
|
||||
match Self::first_valid_default_path() {
|
||||
Some(path) => Self::from_paths(&[path]),
|
||||
#[cfg(feature = "wizard")]
|
||||
None => Self::from_wizard(&Self::default_path()?).await,
|
||||
#[cfg(not(feature = "wizard"))]
|
||||
None => color_eyre::eyre::bail!("cannot find config file from default paths"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,36 +75,6 @@ impl TomlConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the default configuration path.
|
||||
///
|
||||
/// Returns an error if the XDG configuration directory cannot be
|
||||
/// found.
|
||||
pub fn default_path() -> Result<PathBuf> {
|
||||
Ok(config_dir()
|
||||
.ok_or(eyre!("cannot get XDG config directory"))?
|
||||
.join("himalaya")
|
||||
.join("config.toml"))
|
||||
}
|
||||
|
||||
/// Get the first default configuration path that points to a
|
||||
/// valid file.
|
||||
///
|
||||
/// Tries paths in this order:
|
||||
///
|
||||
/// - `$XDG_CONFIG_DIR/himalaya/config.toml` (or equivalent to
|
||||
/// `$XDG_CONFIG_DIR` in other OSes.)
|
||||
/// - `$HOME/.config/himalaya/config.toml`
|
||||
/// - `$HOME/.himalayarc`
|
||||
pub fn first_valid_default_path() -> Option<PathBuf> {
|
||||
Self::default_path()
|
||||
.ok()
|
||||
.filter(|p| p.exists())
|
||||
.or_else(|| home_dir().map(|p| p.join(".config").join("himalaya").join("config.toml")))
|
||||
.filter(|p| p.exists())
|
||||
.or_else(|| home_dir().map(|p| p.join(".himalayarc")))
|
||||
.filter(|p| p.exists())
|
||||
}
|
||||
|
||||
pub fn into_toml_account_config(
|
||||
&self,
|
||||
account_name: Option<&str>,
|
||||
|
@ -241,7 +122,7 @@ impl TomlConfig {
|
|||
) -> Result<(Arc<TomlAccountConfig>, Arc<AccountConfig>)> {
|
||||
let (account_name, toml_account_config) = self.into_toml_account_config(account_name)?;
|
||||
|
||||
let config = Config {
|
||||
let config = email::config::Config {
|
||||
display_name: self.display_name,
|
||||
signature: self.signature,
|
||||
signature_delim: self.signature_delim,
|
||||
|
@ -286,6 +167,38 @@ impl TomlConfig {
|
|||
|
||||
Ok((Arc::new(toml_account_config), Arc::new(account_config)))
|
||||
}
|
||||
|
||||
pub fn account_list_table_preset(&self) -> Option<String> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.preset.clone())
|
||||
}
|
||||
|
||||
pub fn account_list_table_name_color(&self) -> Option<Color> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.name_color)
|
||||
}
|
||||
|
||||
pub fn account_list_table_backends_color(&self) -> Option<Color> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.backends_color)
|
||||
}
|
||||
|
||||
pub fn account_list_table_default_color(&self) -> Option<Color> {
|
||||
self.account
|
||||
.as_ref()
|
||||
.and_then(|account| account.list.as_ref())
|
||||
.and_then(|list| list.table.as_ref())
|
||||
.and_then(|table| table.default_color)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a configuration file path as [`PathBuf`].
|
||||
|
|
|
@ -6,12 +6,12 @@ use toml_edit::{DocumentMut, Table};
|
|||
|
||||
use crate::account;
|
||||
|
||||
use super::TomlConfig;
|
||||
use super::Config;
|
||||
|
||||
pub async fn configure(path: &PathBuf) -> Result<TomlConfig> {
|
||||
pub async fn configure(path: &PathBuf) -> Result<Config> {
|
||||
print::section("Configuring your default account");
|
||||
|
||||
let mut config = TomlConfig::default();
|
||||
let mut config = Config::default();
|
||||
|
||||
let (account_name, account_config) = account::wizard::configure().await?;
|
||||
config.accounts.insert(account_name, account_config);
|
||||
|
@ -27,7 +27,7 @@ pub async fn configure(path: &PathBuf) -> Result<TomlConfig> {
|
|||
Ok(config)
|
||||
}
|
||||
|
||||
fn pretty_serialize(config: &TomlConfig) -> Result<String> {
|
||||
fn pretty_serialize(config: &Config) -> Result<String> {
|
||||
let mut doc: DocumentMut = toml::to_string(&config)?.parse()?;
|
||||
|
||||
doc.iter_mut().for_each(|(_, item)| {
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::process::exit;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
envelope::EnvelopesTable, folder::arg::name::FolderNameOptionalFlag, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -132,7 +132,7 @@ impl Default for ListEnvelopesCommand {
|
|||
}
|
||||
|
||||
impl ListEnvelopesCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing list envelopes command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -4,7 +4,7 @@ pub mod thread;
|
|||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::{list::ListEnvelopesCommand, thread::ThreadEnvelopesCommand};
|
||||
|
||||
|
@ -25,7 +25,7 @@ pub enum EnvelopeSubcommand {
|
|||
|
||||
impl EnvelopeSubcommand {
|
||||
#[allow(unused)]
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::List(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Thread(cmd) => cmd.execute(printer, config).await,
|
||||
|
|
|
@ -9,8 +9,8 @@ use std::process::exit;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
envelope::EnvelopesTree, folder::arg::name::FolderNameOptionalFlag, printer::Printer,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config, envelope::EnvelopesTree,
|
||||
folder::arg::name::FolderNameOptionalFlag, printer::Printer,
|
||||
};
|
||||
|
||||
/// Thread all envelopes.
|
||||
|
@ -34,7 +34,7 @@ pub struct ThreadEnvelopesCommand {
|
|||
}
|
||||
|
||||
impl ThreadEnvelopesCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing thread envelopes command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
|
@ -29,7 +29,7 @@ pub struct FlagAddCommand {
|
|||
}
|
||||
|
||||
impl FlagAddCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing add flag(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -2,10 +2,10 @@ mod add;
|
|||
mod remove;
|
||||
mod set;
|
||||
|
||||
use color_eyre::Result;
|
||||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::{add::FlagAddCommand, remove::FlagRemoveCommand, set::FlagSetCommand};
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub enum FlagSubcommand {
|
|||
|
||||
impl FlagSubcommand {
|
||||
#[allow(unused)]
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::Add(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Set(cmd) => cmd.execute(printer, config).await,
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
|
@ -29,7 +29,7 @@ pub struct FlagRemoveCommand {
|
|||
}
|
||||
|
||||
impl FlagRemoveCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing remove flag(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
|
@ -29,7 +29,7 @@ pub struct FlagSetCommand {
|
|||
}
|
||||
|
||||
impl FlagSetCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing set flag(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ pub struct AttachmentDownloadCommand {
|
|||
}
|
||||
|
||||
impl AttachmentDownloadCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing download attachment(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
mod download;
|
||||
|
||||
use color_eyre::Result;
|
||||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::download::AttachmentDownloadCommand;
|
||||
|
||||
|
@ -19,7 +19,7 @@ pub enum AttachmentSubcommand {
|
|||
}
|
||||
|
||||
impl AttachmentSubcommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::Download(cmd) => cmd.execute(printer, config).await,
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
envelope::arg::ids::EnvelopeIdsArgs,
|
||||
folder::arg::name::{SourceFolderNameOptionalFlag, TargetFolderNameArg},
|
||||
printer::Printer,
|
||||
|
@ -29,7 +29,7 @@ pub struct MessageCopyCommand {
|
|||
}
|
||||
|
||||
impl MessageCopyCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing copy message(s) command");
|
||||
|
||||
let source = &self.source_folder.name;
|
||||
|
|
|
@ -4,7 +4,7 @@ use email::backend::feature::BackendFeatureSource;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ pub struct MessageDeleteCommand {
|
|||
}
|
||||
|
||||
impl MessageDeleteCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing delete message(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
envelope::arg::ids::EnvelopeIdArg,
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
|
||||
|
@ -39,7 +39,7 @@ pub struct MessageForwardCommand {
|
|||
}
|
||||
|
||||
impl MessageForwardCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing forward message command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, printer::Printer,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config, printer::Printer,
|
||||
ui::editor,
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ impl MessageMailtoCommand {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing mailto message command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -13,7 +13,7 @@ pub mod write;
|
|||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::{
|
||||
copy::MessageCopyCommand, delete::MessageDeleteCommand, forward::MessageForwardCommand,
|
||||
|
@ -67,7 +67,7 @@ pub enum MessageSubcommand {
|
|||
|
||||
impl MessageSubcommand {
|
||||
#[allow(unused)]
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::Read(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Thread(cmd) => cmd.execute(printer, config).await,
|
||||
|
|
|
@ -7,7 +7,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
envelope::arg::ids::EnvelopeIdsArgs,
|
||||
folder::arg::name::{SourceFolderNameOptionalFlag, TargetFolderNameArg},
|
||||
printer::Printer,
|
||||
|
@ -30,7 +30,7 @@ pub struct MessageMoveCommand {
|
|||
}
|
||||
|
||||
impl MessageMoveCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing move message(s) command");
|
||||
|
||||
let source = &self.source_folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
|
||||
#[allow(unused)]
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ pub struct MessageReadCommand {
|
|||
}
|
||||
|
||||
impl MessageReadCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing read message(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
envelope::arg::ids::EnvelopeIdArg,
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs, reply::MessageReplyAllArg},
|
||||
|
@ -42,7 +42,7 @@ pub struct MessageReplyCommand {
|
|||
}
|
||||
|
||||
impl MessageReplyCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing reply message command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
|
||||
#[allow(unused)]
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
folder::arg::name::FolderNameOptionalFlag, message::arg::MessageRawArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub struct MessageSaveCommand {
|
|||
}
|
||||
|
||||
impl MessageSaveCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing save message command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::io::{self, BufRead, IsTerminal};
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
message::arg::MessageRawArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@ pub struct MessageSendCommand {
|
|||
}
|
||||
|
||||
impl MessageSendCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing send message command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -7,7 +7,7 @@ use tracing::info;
|
|||
use crate::envelope::arg::ids::EnvelopeIdArg;
|
||||
#[allow(unused)]
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ pub struct MessageThreadCommand {
|
|||
}
|
||||
|
||||
impl MessageThreadCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing thread message(s) command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
|
||||
printer::Printer,
|
||||
ui::editor,
|
||||
|
@ -31,7 +31,7 @@ pub struct MessageWriteCommand {
|
|||
}
|
||||
|
||||
impl MessageWriteCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing write message command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
envelope::arg::ids::EnvelopeIdArg,
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
|
||||
|
@ -37,7 +37,7 @@ pub struct TemplateForwardCommand {
|
|||
}
|
||||
|
||||
impl TemplateForwardCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing forward template command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -4,10 +4,10 @@ mod save;
|
|||
mod send;
|
||||
mod write;
|
||||
|
||||
use color_eyre::Result;
|
||||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::{
|
||||
forward::TemplateForwardCommand, reply::TemplateReplyCommand, save::TemplateSaveCommand,
|
||||
|
@ -43,7 +43,7 @@ pub enum TemplateSubcommand {
|
|||
}
|
||||
|
||||
impl TemplateSubcommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::Write(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Reply(cmd) => cmd.execute(printer, config).await,
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
envelope::arg::ids::EnvelopeIdArg,
|
||||
folder::arg::name::FolderNameOptionalFlag,
|
||||
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs, reply::MessageReplyAllArg},
|
||||
|
@ -41,7 +41,7 @@ pub struct TemplateReplyCommand {
|
|||
}
|
||||
|
||||
impl TemplateReplyCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing reply template command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::io::{self, BufRead, IsTerminal};
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
email::template::arg::TemplateRawArg, folder::arg::name::FolderNameOptionalFlag,
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -30,7 +30,7 @@ pub struct TemplateSaveCommand {
|
|||
}
|
||||
|
||||
impl TemplateSaveCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing save template command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::io::{self, BufRead, IsTerminal};
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
email::template::arg::TemplateRawArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub struct TemplateSendCommand {
|
|||
}
|
||||
|
||||
impl TemplateSendCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing send template command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -4,7 +4,7 @@ use email::message::Message;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, config::Config,
|
||||
email::template::arg::body::TemplateRawBodyArg, message::arg::header::HeaderRawArgs,
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ pub struct TemplateWriteCommand {
|
|||
}
|
||||
|
||||
impl TemplateWriteCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing write template command");
|
||||
|
||||
let (_, account_config) = config
|
||||
|
|
|
@ -4,7 +4,7 @@ use email::{backend::feature::BackendFeatureSource, folder::add::AddFolder};
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
folder::arg::name::FolderNameArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,7 @@ pub struct AddFolderCommand {
|
|||
}
|
||||
|
||||
impl AddFolderCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing create folder command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -7,7 +7,7 @@ use pimalaya_tui::prompt;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
folder::arg::name::FolderNameArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@ pub struct FolderDeleteCommand {
|
|||
}
|
||||
|
||||
impl FolderDeleteCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing delete folder command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -4,7 +4,7 @@ use email::{backend::feature::BackendFeatureSource, folder::expunge::ExpungeFold
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
folder::arg::name::FolderNameArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@ pub struct FolderExpungeCommand {
|
|||
}
|
||||
|
||||
impl FolderExpungeCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing expunge folder command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
|
@ -6,7 +6,7 @@ use tracing::info;
|
|||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
config::TomlConfig,
|
||||
config::Config,
|
||||
folder::{Folders, FoldersTable},
|
||||
printer::Printer,
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ pub struct FolderListCommand {
|
|||
}
|
||||
|
||||
impl FolderListCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing list folders command");
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
|
|
|
@ -4,10 +4,10 @@ mod expunge;
|
|||
mod list;
|
||||
mod purge;
|
||||
|
||||
use color_eyre::Result;
|
||||
use clap::Subcommand;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
use crate::{config::Config, printer::Printer};
|
||||
|
||||
use self::{
|
||||
add::AddFolderCommand, delete::FolderDeleteCommand, expunge::FolderExpungeCommand,
|
||||
|
@ -38,7 +38,7 @@ pub enum FolderSubcommand {
|
|||
|
||||
impl FolderSubcommand {
|
||||
#[allow(unused)]
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
match self {
|
||||
Self::Add(cmd) => cmd.execute(printer, config).await,
|
||||
Self::List(cmd) => cmd.execute(printer, config).await,
|
||||
|
|
|
@ -7,7 +7,7 @@ use pimalaya_tui::prompt;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig,
|
||||
account::arg::name::AccountNameFlag, backend::Backend, config::Config,
|
||||
folder::arg::name::FolderNameArg, printer::Printer,
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@ pub struct FolderPurgeCommand {
|
|||
}
|
||||
|
||||
impl FolderPurgeCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &Config) -> Result<()> {
|
||||
info!("executing purge folder command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
|
34
src/main.rs
34
src/main.rs
|
@ -1,24 +1,14 @@
|
|||
use clap::Parser;
|
||||
use color_eyre::{Result, Section};
|
||||
use color_eyre::Result;
|
||||
use himalaya::{
|
||||
cli::Cli, config::TomlConfig, envelope::command::list::ListEnvelopesCommand,
|
||||
cli::Cli, config::Config, envelope::command::list::ListEnvelopesCommand,
|
||||
message::command::mailto::MessageMailtoCommand, printer::StdoutPrinter,
|
||||
};
|
||||
use std::env;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use pimalaya_tui::cli::tracing;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
if env::var("RUST_LOG").is_err() {
|
||||
if std::env::args().any(|arg| arg == "--debug") {
|
||||
env::set_var("RUST_LOG", "debug");
|
||||
}
|
||||
if std::env::args().any(|arg| arg == "--trace") {
|
||||
env::set_var("RUST_LOG", "trace");
|
||||
}
|
||||
}
|
||||
|
||||
let filter = himalaya::tracing::install()?;
|
||||
let tracing = tracing::install()?;
|
||||
|
||||
// if the first argument starts by "mailto:", execute straight the
|
||||
// mailto message command
|
||||
|
@ -28,7 +18,7 @@ async fn main() -> Result<()> {
|
|||
|
||||
if let Some(ref url) = mailto {
|
||||
let mut printer = StdoutPrinter::default();
|
||||
let config = TomlConfig::from_default_paths().await?;
|
||||
let config = Config::from_default_paths().await?;
|
||||
|
||||
return MessageMailtoCommand::new(url)?
|
||||
.execute(&mut printer, &config)
|
||||
|
@ -37,23 +27,15 @@ async fn main() -> Result<()> {
|
|||
|
||||
let cli = Cli::parse();
|
||||
let mut printer = StdoutPrinter::new(cli.output);
|
||||
let mut res = match cli.command {
|
||||
let res = match cli.command {
|
||||
Some(cmd) => cmd.execute(&mut printer, cli.config_paths.as_ref()).await,
|
||||
None => {
|
||||
let config = TomlConfig::from_paths_or_default(cli.config_paths.as_ref()).await?;
|
||||
let config = Config::from_paths_or_default(cli.config_paths.as_ref()).await?;
|
||||
ListEnvelopesCommand::default()
|
||||
.execute(&mut printer, &config)
|
||||
.await
|
||||
}
|
||||
};
|
||||
|
||||
if filter < LevelFilter::DEBUG {
|
||||
res = res.note("Run with --debug to enable logs with spantrace.");
|
||||
};
|
||||
|
||||
if filter < LevelFilter::TRACE {
|
||||
res = res.note("Run with --trace to enable verbose logs with backtrace.")
|
||||
};
|
||||
|
||||
res
|
||||
tracing.with_debug_and_trace_notes(res)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use clap::ValueEnum;
|
||||
use color_eyre::{eyre::eyre, eyre::Error, Result};
|
||||
use color_eyre::{
|
||||
eyre::{bail, Error},
|
||||
Result,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use std::{fmt, str::FromStr};
|
||||
|
||||
|
@ -18,7 +21,7 @@ impl FromStr for OutputFmt {
|
|||
match fmt {
|
||||
fmt if fmt.eq_ignore_ascii_case("json") => Ok(Self::Json),
|
||||
fmt if fmt.eq_ignore_ascii_case("plain") => Ok(Self::Plain),
|
||||
unknown => Err(eyre!("cannot parse output format {}", unknown)),
|
||||
unknown => bail!("cannot parse output format {unknown}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use color_eyre::{eyre::Context, Result};
|
||||
use std::{
|
||||
fmt,
|
||||
io::{self, Write},
|
||||
io::{stderr, stdout, Stderr, Stdout, Write},
|
||||
};
|
||||
|
||||
use color_eyre::{eyre::Context, Result};
|
||||
|
||||
use crate::output::OutputFmt;
|
||||
|
||||
pub trait PrintTable {
|
||||
fn print(&self, writer: &mut dyn io::Write, table_max_width: Option<u16>) -> Result<()>;
|
||||
fn print(&self, writer: &mut dyn Write, table_max_width: Option<u16>) -> Result<()>;
|
||||
}
|
||||
|
||||
pub trait Printer {
|
||||
|
@ -23,16 +24,16 @@ pub trait Printer {
|
|||
}
|
||||
|
||||
pub struct StdoutPrinter {
|
||||
stdout: io::Stdout,
|
||||
stderr: io::Stderr,
|
||||
stdout: Stdout,
|
||||
stderr: Stderr,
|
||||
output: OutputFmt,
|
||||
}
|
||||
|
||||
impl StdoutPrinter {
|
||||
pub fn new(output: OutputFmt) -> Self {
|
||||
Self {
|
||||
stdout: io::stdout(),
|
||||
stderr: io::stderr(),
|
||||
stdout: stdout(),
|
||||
stderr: stderr(),
|
||||
output,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue