clean doc

This commit is contained in:
Clément DOUIN
2023-12-08 12:18:18 +01:00
parent fff11fbe20
commit ef3214f36f
52 changed files with 452 additions and 318 deletions
+3 -3
View File
@@ -5,14 +5,14 @@ use log::info;
use crate::{
account::arg::name::AccountNameFlag,
backend::Backend,
cache::arg::disable::DisableCacheFlag,
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::{SourceFolderNameArg, TargetFolderNameArg},
printer::Printer,
};
/// Copy a message from a source folder to a target folder
/// Copy a message from a source folder to a target folder.
#[derive(Debug, Parser)]
pub struct MessageCopyCommand {
#[command(flatten)]
@@ -25,7 +25,7 @@ pub struct MessageCopyCommand {
pub envelopes: EnvelopeIdsArgs,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
+8 -3
View File
@@ -3,12 +3,17 @@ use clap::Parser;
use log::info;
use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::DisableCacheFlag,
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameArg,
printer::Printer,
};
/// Delete a message from a folder
/// Mark as deleted a message from a folder.
///
/// This command does not really delete the message: if the given
/// folder points to the trash folder, it adds the "deleted" flag to
/// its envelope, otherwise it moves it to the trash folder. Only the
/// expunge folder command truly deletes messages.
#[derive(Debug, Parser)]
pub struct MessageDeleteCommand {
#[command(flatten)]
@@ -18,7 +23,7 @@ pub struct MessageDeleteCommand {
pub envelopes: EnvelopeIdsArgs,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
+10 -9
View File
@@ -7,16 +7,21 @@ use std::io::{self, BufRead};
use crate::{
account::arg::name::AccountNameFlag,
backend::Backend,
cache::arg::disable::DisableCacheFlag,
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg,
folder::arg::name::FolderNameArg,
message::arg::{body::BodyRawArg, header::HeaderRawArgs},
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
printer::Printer,
ui::editor,
};
/// Forward a new message
/// Forward a message.
///
/// This command allows you to forward the given message using the
/// editor defined in your environment variable $EDITOR. When the
/// edition process finishes, you can choose between saving or sending
/// the final message.
#[derive(Debug, Parser)]
pub struct MessageForwardCommand {
#[command(flatten)]
@@ -25,18 +30,14 @@ pub struct MessageForwardCommand {
#[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,
pub body: MessageRawBodyArg,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
+24 -4
View File
@@ -1,20 +1,30 @@
use anyhow::Result;
use clap::Parser;
use log::info;
use log::{debug, 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
/// Parse and edit a message from a mailto URL string.
///
/// This command allows you to edit a message from the mailto format
/// using the editor defined in your environment variable
/// $EDITOR. When the edition process finishes, you can choose between
/// saving or sending the final message.
#[derive(Debug, Parser)]
pub struct MessageMailtoCommand {
/// The mailto url
/// The mailto url.
#[arg()]
pub url: Url,
}
impl MessageMailtoCommand {
pub fn new(url: &str) -> Result<Self> {
let url = Url::parse(url)?;
Ok(Self { url })
}
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message mailto command");
@@ -23,17 +33,27 @@ impl MessageMailtoCommand {
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;
let mut builder = MessageBuilder::new().to(self.url.path());
let mut body = String::new();
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),
b"body" => body += &val,
_ => (),
}
}
match account_config.signature() {
Ok(Some(ref signature)) => builder = builder.text_body(body + "\n\n" + signature),
Ok(None) => builder = builder.text_body(body),
Err(err) => {
debug!("cannot add signature to mailto message, skipping it: {err}");
debug!("{err:?}");
}
}
let tpl = account_config
.generate_tpl_interpreter()
.with_show_only_headers(account_config.email_writing_headers())
+7 -12
View File
@@ -21,47 +21,42 @@ use self::{
write::MessageWriteCommand,
};
/// Subcommand to manage messages
/// Manage messages.
///
/// A message is the content of an email. It is composed of headers
/// (located at the top of the message) and a body (located at the
/// bottom of the message). Both are separated by two new lines. This
/// subcommand allows you to manage them.
#[derive(Debug, Subcommand)]
pub enum MessageSubcommand {
/// Read a message
#[command(arg_required_else_help = true)]
Read(MessageReadCommand),
/// Write a new message
#[command(alias = "new", alias = "compose")]
#[command(alias = "add", alias = "create", alias = "new", alias = "compose")]
Write(MessageWriteCommand),
/// Reply to a message
#[command()]
Reply(MessageReplyCommand),
/// Forward a message
#[command(alias = "fwd")]
Forward(MessageForwardCommand),
/// Parse and edit a message from a mailto URL string
#[command()]
Mailto(MessageMailtoCommand),
/// Save a message to a folder
#[command(arg_required_else_help = true)]
#[command(alias = "add", alias = "create")]
Save(MessageSaveCommand),
/// Send a message
#[command(arg_required_else_help = true)]
Send(MessageSendCommand),
/// Copy a message from a source folder to a target folder
#[command(arg_required_else_help = true)]
Copy(MessageCopyCommand),
/// Move a message from a source folder to a target folder
#[command(arg_required_else_help = true)]
Move(MessageMoveCommand),
/// Delete a message from a folder
#[command(arg_required_else_help = true)]
Delete(MessageDeleteCommand),
}
+3 -3
View File
@@ -5,14 +5,14 @@ use log::info;
use crate::{
account::arg::name::AccountNameFlag,
backend::Backend,
cache::arg::disable::DisableCacheFlag,
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::{SourceFolderNameArg, TargetFolderNameArg},
printer::Printer,
};
/// Move a message from a source folder to a target folder
/// Move a message from a source folder to a target folder.
#[derive(Debug, Parser)]
pub struct MessageMoveCommand {
#[command(flatten)]
@@ -25,7 +25,7 @@ pub struct MessageMoveCommand {
pub envelopes: EnvelopeIdsArgs,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
+12 -10
View File
@@ -4,12 +4,14 @@ use log::info;
use mml::message::FilterParts;
use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::DisableCacheFlag,
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameArg,
printer::Printer,
};
/// Read a message from a folder
/// Read a message.
///
/// This command allows you to read a message.
#[derive(Debug, Parser)]
pub struct MessageReadCommand {
#[command(flatten)]
@@ -18,18 +20,18 @@ pub struct MessageReadCommand {
#[command(flatten)]
pub envelopes: EnvelopeIdsArgs,
/// Read the raw version of the message
/// Read the raw version of the given message.
///
/// The raw message represents the message as it is on the
/// backend, unedited: not decoded nor decrypted. This is useful
/// for debugging faulty messages, but also for
/// The raw message represents the headers and the body as it is
/// on the backend, unedited: not decoded nor decrypted. This is
/// useful for debugging faulty messages, but also for
/// saving/sending/transfering messages.
#[arg(long, short)]
#[arg(conflicts_with = "no_headers")]
#[arg(conflicts_with = "headers")]
pub raw: bool,
/// Read only body of text/html parts
/// Read only body of text/html parts.
///
/// This argument is useful when you need to read the HTML version
/// of a message. Combined with --no-headers, you can write it to
@@ -38,7 +40,7 @@ pub struct MessageReadCommand {
#[arg(conflicts_with = "raw")]
pub html: bool,
/// Read only the body of the message
/// Read only the body of the message.
///
/// All headers will be removed from the message.
#[arg(long)]
@@ -47,7 +49,7 @@ pub struct MessageReadCommand {
pub no_headers: bool,
/// List of headers that should be visible at the top of the
/// message
/// message.
///
/// If a given header is not found in the message, it will not be
/// visible. If no header is given, defaults to the one set up in
@@ -58,7 +60,7 @@ pub struct MessageReadCommand {
pub headers: Vec<String>,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
+10 -5
View File
@@ -8,16 +8,21 @@ use std::io::{self, BufRead};
use crate::{
account::arg::name::AccountNameFlag,
backend::Backend,
cache::arg::disable::DisableCacheFlag,
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg,
folder::arg::name::FolderNameArg,
message::arg::{body::BodyRawArg, header::HeaderRawArgs, reply::MessageReplyAllArg},
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs, reply::MessageReplyAllArg},
printer::Printer,
ui::editor,
};
/// Reply a new message
/// Reply to a message.
///
/// This command allows you to reply to the given message using the
/// editor defined in your environment variable $EDITOR. When the
/// edition process finishes, you can choose between saving or sending
/// the final message.
#[derive(Debug, Parser)]
pub struct MessageReplyCommand {
#[command(flatten)]
@@ -33,10 +38,10 @@ pub struct MessageReplyCommand {
pub headers: HeaderRawArgs,
#[command(flatten)]
pub body: BodyRawArg,
pub body: MessageRawBodyArg,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
+12 -13
View File
@@ -5,22 +5,24 @@ use log::info;
use std::io::{self, BufRead};
use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::DisableCacheFlag,
config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer,
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, folder::arg::name::FolderNameArg, message::arg::body::MessageRawBodyArg,
printer::Printer,
};
/// Save a message to a folder
/// Save a message to a folder.
///
/// This command allows you to add a raw message to the given folder.
#[derive(Debug, Parser)]
pub struct MessageSaveCommand {
#[command(flatten)]
pub folder: FolderNameArg,
/// The raw message to save
#[arg(value_name = "MESSAGE", raw = true)]
pub raw: String,
#[command(flatten)]
pub body: MessageRawBodyArg,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
@@ -33,7 +35,6 @@ impl MessageSaveCommand {
let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let raw_msg = &self.raw;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
@@ -41,8 +42,8 @@ impl MessageSaveCommand {
let is_tty = atty::is(Stream::Stdin);
let is_json = printer.is_json();
let raw_email = if is_tty || is_json {
raw_msg.replace("\r", "").replace("\n", "\r\n")
let msg = if is_tty || is_json {
self.body.raw()
} else {
io::stdin()
.lock()
@@ -52,9 +53,7 @@ impl MessageSaveCommand {
.join("\r\n")
};
backend
.add_raw_message(folder, raw_email.as_bytes())
.await?;
backend.add_raw_message(folder, msg.as_bytes()).await?;
printer.print(format!("Message successfully saved to {folder}!"))
}
+13 -12
View File
@@ -6,19 +6,21 @@ use log::info;
use std::io::{self, BufRead};
use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::DisableCacheFlag,
config::TomlConfig, printer::Printer,
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, message::arg::body::MessageRawBodyArg, printer::Printer,
};
/// Send a message from a folder
/// Send a message.
///
/// This command allows you to send a raw message and to save a copy
/// to your send folder.
#[derive(Debug, Parser)]
pub struct MessageSendCommand {
/// The raw message to send
#[arg(value_name = "MESSAGE", raw = true)]
pub raw: String,
#[command(flatten)]
pub body: MessageRawBodyArg,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,
@@ -30,7 +32,6 @@ impl MessageSendCommand {
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let raw_msg = &self.raw;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
@@ -39,8 +40,8 @@ impl MessageSendCommand {
let is_tty = atty::is(Stream::Stdin);
let is_json = printer.is_json();
let raw_email = if is_tty || is_json {
raw_msg.replace("\r", "").replace("\n", "\r\n")
let msg = if is_tty || is_json {
self.body.raw()
} else {
io::stdin()
.lock()
@@ -50,11 +51,11 @@ impl MessageSendCommand {
.join("\r\n")
};
backend.send_raw_message(raw_email.as_bytes()).await?;
backend.send_raw_message(msg.as_bytes()).await?;
if account_config.email_sending_save_copy.unwrap_or_default() {
backend
.add_raw_message_with_flag(&folder, raw_email.as_bytes(), Flag::Seen)
.add_raw_message_with_flag(&folder, msg.as_bytes(), Flag::Seen)
.await?;
printer.print(format!("Message successfully sent and saved to {folder}!"))
+10 -5
View File
@@ -8,24 +8,29 @@ use std::io::{self, BufRead};
use crate::{
account::arg::name::AccountNameFlag,
backend::Backend,
cache::arg::disable::DisableCacheFlag,
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
message::arg::{body::BodyRawArg, header::HeaderRawArgs},
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
printer::Printer,
ui::editor,
};
/// Write a new message
/// Write a new message.
///
/// This command allows you to write a new message using the editor
/// defined in your environment variable $EDITOR. When the edition
/// process finishes, you can choose between saving or sending the
/// final message.
#[derive(Debug, Parser)]
pub struct MessageWriteCommand {
#[command(flatten)]
pub headers: HeaderRawArgs,
#[command(flatten)]
pub body: BodyRawArg,
pub body: MessageRawBodyArg,
#[command(flatten)]
pub cache: DisableCacheFlag,
pub cache: CacheDisableFlag,
#[command(flatten)]
pub account: AccountNameFlag,