melib: add Folder operations in mail backends
Add following operations in mail backend: - Create, - Delete, - Subscribe, - Unsubscribe, - Renamemaster
parent
8b0dff728d
commit
dc2184a9de
|
@ -143,6 +143,18 @@ impl NotifyFn {
|
|||
self.0(f);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub enum FolderOperation {
|
||||
Create,
|
||||
Delete,
|
||||
Subscribe,
|
||||
Unsubscribe,
|
||||
Rename(NewFolderName),
|
||||
}
|
||||
|
||||
type NewFolderName = String;
|
||||
|
||||
pub trait MailBackend: ::std::fmt::Debug {
|
||||
fn get(&mut self, folder: &Folder) -> Async<Result<Vec<Envelope>>>;
|
||||
fn watch(&self, sender: RefreshEventConsumer) -> Result<()>;
|
||||
|
@ -150,6 +162,9 @@ pub trait MailBackend: ::std::fmt::Debug {
|
|||
fn operation(&self, hash: EnvelopeHash, folder_hash: FolderHash) -> Box<BackendOp>;
|
||||
|
||||
fn save(&self, bytes: &[u8], folder: &str) -> Result<()>;
|
||||
fn folder_operation(&mut self, path: &str, op: FolderOperation) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
//login function
|
||||
}
|
||||
|
||||
|
|
|
@ -110,3 +110,10 @@ impl From<str::Utf8Error> for MeliError {
|
|||
// MeliError::new(format!("{:?}", kind))
|
||||
// }
|
||||
//}
|
||||
|
||||
impl<T> From<std::sync::PoisonError<T>> for MeliError {
|
||||
#[inline]
|
||||
fn from(kind: std::sync::PoisonError<T>) -> MeliError {
|
||||
MeliError::new(format!("{}", kind))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ use super::AccountConf;
|
|||
use fnv::FnvHashMap;
|
||||
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
||||
use melib::backends::{
|
||||
BackendOp, Backends, Folder, FolderHash, MailBackend, NotifyFn, ReadOnlyOp, RefreshEvent,
|
||||
RefreshEventConsumer, RefreshEventKind, SpecialUseMailbox,
|
||||
BackendOp, Backends, Folder, FolderHash, FolderOperation, MailBackend, NotifyFn, ReadOnlyOp,
|
||||
RefreshEvent, RefreshEventConsumer, RefreshEventKind, SpecialUseMailbox,
|
||||
};
|
||||
use melib::error::{MeliError, Result};
|
||||
use melib::mailbox::*;
|
||||
|
@ -601,6 +601,10 @@ impl Account {
|
|||
pub fn thread(&self, h: ThreadHash, f: FolderHash) -> &ThreadNode {
|
||||
&self.collection.threads[&f].thread_nodes()[&h]
|
||||
}
|
||||
|
||||
pub fn folder_operation(&mut self, path: &str, op: FolderOperation) -> Result<()> {
|
||||
self.backend.folder_operation(path, op)
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<FolderHash> for Account {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
/*! A parser module for user commands passed through the Ex mode.
|
||||
*/
|
||||
use melib::backends::FolderOperation;
|
||||
pub use melib::mailbox::{SortField, SortOrder};
|
||||
use nom::{digit, not_line_ending};
|
||||
use std;
|
||||
|
@ -211,6 +212,78 @@ define_commands!([
|
|||
)
|
||||
);
|
||||
)
|
||||
},
|
||||
{ tags: ["create-folder "],
|
||||
desc: "create-folder ACCOUNT FOLDER_PATH",
|
||||
parser:(
|
||||
named!( create_folder<Action>,
|
||||
do_parse!(
|
||||
ws!(tag!("create-folder"))
|
||||
>> account: map_res!(is_not!(" "), std::str::from_utf8)
|
||||
>> is_a!(" ")
|
||||
>> path: map_res!(call!(not_line_ending), std::str::from_utf8)
|
||||
>> (Folder(account.to_string(), path.to_string(), FolderOperation::Create))
|
||||
)
|
||||
);
|
||||
)
|
||||
},
|
||||
{ tags: ["subscribe-folder "],
|
||||
desc: "subscribe-folder ACCOUNT FOLDER_PATH",
|
||||
parser:(
|
||||
named!( sub_folder<Action>,
|
||||
do_parse!(
|
||||
ws!(tag!("subscribe-folder"))
|
||||
>> account: map_res!(is_not!(" "), std::str::from_utf8)
|
||||
>> is_a!(" ")
|
||||
>> path: map_res!(call!(not_line_ending), std::str::from_utf8)
|
||||
>> (Folder(account.to_string(), path.to_string(), FolderOperation::Subscribe))
|
||||
)
|
||||
);
|
||||
)
|
||||
},
|
||||
{ tags: ["unsubscribe-folder "],
|
||||
desc: "unsubscribe-folder ACCOUNT FOLDER_PATH",
|
||||
parser:(
|
||||
named!( unsub_folder<Action>,
|
||||
do_parse!(
|
||||
ws!(tag!("unsubscribe-folder"))
|
||||
>> account: map_res!(is_not!(" "), std::str::from_utf8)
|
||||
>> is_a!(" ")
|
||||
>> path: map_res!(call!(not_line_ending), std::str::from_utf8)
|
||||
>> (Folder(account.to_string(), path.to_string(), FolderOperation::Unsubscribe))
|
||||
)
|
||||
);
|
||||
)
|
||||
},
|
||||
{ tags: ["rename-folder "],
|
||||
desc: "rename-folder ACCOUNT FOLDER_PATH_SRC FOLDER_PATH_DEST",
|
||||
parser:(
|
||||
named!( rename_folder<Action>,
|
||||
do_parse!(
|
||||
ws!(tag!("rename-folder"))
|
||||
>> account: map_res!(is_not!(" "), std::str::from_utf8)
|
||||
>> is_a!(" ")
|
||||
>> src: map_res!(is_not!(" "), std::str::from_utf8)
|
||||
>> is_a!(" ")
|
||||
>> dest: map_res!(call!(not_line_ending), std::str::from_utf8)
|
||||
>> (Folder(account.to_string(), src.to_string(), FolderOperation::Rename(dest.to_string())))
|
||||
)
|
||||
);
|
||||
)
|
||||
},
|
||||
{ tags: ["delete-folder "],
|
||||
desc: "delete-folder ACCOUNT FOLDER_PATH",
|
||||
parser:(
|
||||
named!( delete_folder<Action>,
|
||||
do_parse!(
|
||||
ws!(tag!("delete-folder"))
|
||||
>> account: map_res!(is_not!(" "), std::str::from_utf8)
|
||||
>> is_a!(" ")
|
||||
>> path: map_res!(call!(not_line_ending), std::str::from_utf8)
|
||||
>> (Folder(account.to_string(), path.to_string(), FolderOperation::Delete))
|
||||
)
|
||||
);
|
||||
)
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -263,5 +336,5 @@ named!(
|
|||
);
|
||||
|
||||
named!(pub parse_command<Action>,
|
||||
alt_complete!( goto | listing_action | sort | subsort | close | mailinglist | setenv | printenv | pipe | compose_action)
|
||||
alt_complete!( goto | listing_action | sort | subsort | close | mailinglist | setenv | printenv | pipe | compose_action | create_folder | sub_folder | unsub_folder | delete_folder | rename_folder)
|
||||
);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
use crate::components::Component;
|
||||
use melib::backends::FolderOperation;
|
||||
pub use melib::mailbox::{SortField, SortOrder};
|
||||
use melib::thread::ThreadHash;
|
||||
use melib::{Draft, EnvelopeHash};
|
||||
|
@ -83,4 +84,8 @@ pub enum Action {
|
|||
SetEnv(String, String),
|
||||
PrintEnv(String),
|
||||
Compose(ComposeAction),
|
||||
Folder(AccountName, FolderPath, FolderOperation),
|
||||
}
|
||||
|
||||
type AccountName = String;
|
||||
type FolderPath = String;
|
||||
|
|
|
@ -494,10 +494,37 @@ impl State {
|
|||
),
|
||||
));
|
||||
}
|
||||
Folder(account_name, path, op) => {
|
||||
if let Some(account) = self
|
||||
.context
|
||||
.accounts
|
||||
.iter_mut()
|
||||
.find(|a| a.name() == account_name)
|
||||
{
|
||||
if let Err(e) = account.folder_operation(&path, op) {
|
||||
self.context.replies.push_back(UIEvent::StatusEvent(
|
||||
StatusEvent::DisplayMessage(e.to_string()),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
self.context.replies.push_back(UIEvent::StatusEvent(
|
||||
StatusEvent::DisplayMessage(format!(
|
||||
"Account with name `{}` not found.",
|
||||
account_name
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
v => {
|
||||
self.rcv_event(UIEvent::Action(v));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
|
||||
"invalid command".to_string(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue