-
-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor message with clap derive api (part 2)
- Loading branch information
Showing
18 changed files
with
413 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use std::ops::Deref; | ||
|
||
use clap::Parser; | ||
|
||
/// The raw message body argument parser | ||
#[derive(Debug, Parser)] | ||
pub struct BodyRawArg { | ||
/// Prefill the template with a custom body | ||
#[arg(raw = true, required = false)] | ||
#[arg(name = "body-raw", value_delimiter = ' ')] | ||
pub raw: Vec<String>, | ||
} | ||
|
||
impl BodyRawArg { | ||
pub fn raw(self) -> String { | ||
self.raw.join(" ").replace("\r", "").replace("\n", "\r\n") | ||
} | ||
} | ||
|
||
impl Deref for BodyRawArg { | ||
type Target = Vec<String>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.raw | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use clap::Parser; | ||
|
||
/// The envelope id argument parser | ||
#[derive(Debug, Parser)] | ||
pub struct HeaderRawArgs { | ||
/// Prefill the template with custom headers | ||
/// | ||
/// A raw header should follow the pattern KEY:VAL. | ||
#[arg(long = "header", short = 'H', required = false)] | ||
#[arg(name = "header-raw", value_name = "KEY:VAL", value_parser = raw_header_parser)] | ||
pub raw: Vec<(String, String)>, | ||
} | ||
|
||
pub fn raw_header_parser(raw_header: &str) -> Result<(String, String), String> { | ||
if let Some((key, val)) = raw_header.split_once(":") { | ||
Ok((key.trim().to_owned(), val.trim().to_owned())) | ||
} else { | ||
Err(format!("cannot parse raw header {raw_header:?}")) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod body; | ||
pub mod header; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use anyhow::{anyhow, Result}; | ||
use atty::Stream; | ||
use clap::Parser; | ||
use log::info; | ||
use std::io::{self, BufRead}; | ||
|
||
use crate::{ | ||
account::arg::name::AccountNameFlag, | ||
backend::Backend, | ||
cache::arg::disable::DisableCacheFlag, | ||
config::TomlConfig, | ||
envelope::arg::ids::EnvelopeIdArg, | ||
folder::arg::name::FolderNameArg, | ||
message::arg::{body::BodyRawArg, header::HeaderRawArgs}, | ||
printer::Printer, | ||
ui::editor, | ||
}; | ||
|
||
/// Forward a new message | ||
#[derive(Debug, Parser)] | ||
pub struct MessageForwardCommand { | ||
#[command(flatten)] | ||
pub folder: FolderNameArg, | ||
|
||
#[command(flatten)] | ||
pub envelope: EnvelopeIdArg, | ||
|
||
/// Forward to all recipients | ||
#[arg(long, short = 'A')] | ||
pub all: bool, | ||
|
||
#[command(flatten)] | ||
pub headers: HeaderRawArgs, | ||
|
||
#[command(flatten)] | ||
pub body: BodyRawArg, | ||
|
||
#[command(flatten)] | ||
pub cache: DisableCacheFlag, | ||
|
||
#[command(flatten)] | ||
pub account: AccountNameFlag, | ||
} | ||
|
||
impl MessageForwardCommand { | ||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { | ||
info!("executing message forward command"); | ||
|
||
let folder = &self.folder.name; | ||
let account = self.account.name.as_ref().map(String::as_str); | ||
let cache = self.cache.disable; | ||
|
||
let (toml_account_config, account_config) = | ||
config.clone().into_account_configs(account, cache)?; | ||
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; | ||
|
||
let is_tty = atty::is(Stream::Stdin); | ||
let is_json = printer.is_json(); | ||
let body = if !self.body.is_empty() && (is_tty || is_json) { | ||
self.body.raw() | ||
} else { | ||
io::stdin() | ||
.lock() | ||
.lines() | ||
.filter_map(Result::ok) | ||
.collect::<Vec<String>>() | ||
.join("\r\n") | ||
}; | ||
|
||
let id = self.envelope.id; | ||
let tpl = backend | ||
.get_messages(folder, &[id]) | ||
.await? | ||
.first() | ||
.ok_or(anyhow!("cannot find message"))? | ||
.to_forward_tpl_builder(&account_config) | ||
.with_headers(self.headers.raw) | ||
.with_body(body) | ||
.build() | ||
.await?; | ||
editor::edit_tpl_with_editor(&account_config, printer, &backend, tpl).await | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
use anyhow::Result; | ||
use clap::Parser; | ||
use log::info; | ||
use mail_builder::MessageBuilder; | ||
use url::Url; | ||
|
||
use crate::{backend::Backend, config::TomlConfig, printer::Printer, ui::editor}; | ||
|
||
/// Parse and edit a message from a mailto URL string | ||
#[derive(Debug, Parser)] | ||
pub struct MessageMailtoCommand { | ||
/// The mailto url | ||
#[arg()] | ||
pub url: Url, | ||
} | ||
|
||
impl MessageMailtoCommand { | ||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { | ||
info!("executing message mailto command"); | ||
|
||
let (toml_account_config, account_config) = | ||
config.clone().into_account_configs(None, false)?; | ||
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; | ||
|
||
let mut builder = MessageBuilder::new().to(self.url.path()); | ||
|
||
for (key, val) in self.url.query_pairs() { | ||
match key.to_lowercase().as_bytes() { | ||
b"cc" => builder = builder.cc(val.to_string()), | ||
b"bcc" => builder = builder.bcc(val.to_string()), | ||
b"subject" => builder = builder.subject(val), | ||
b"body" => builder = builder.text_body(val), | ||
_ => (), | ||
} | ||
} | ||
|
||
let tpl = account_config | ||
.generate_tpl_interpreter() | ||
.with_show_only_headers(account_config.email_writing_headers()) | ||
.build() | ||
.from_msg_builder(builder) | ||
.await?; | ||
|
||
editor::edit_tpl_with_editor(&account_config, printer, &backend, tpl).await | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.