Move all backends to Backends structure
parent
577889f7da
commit
c5dbf4e9ae
|
@ -36,6 +36,13 @@ fn main() {
|
|||
ncurses::setlocale(locale_conf, "en_US.UTF-8");
|
||||
let set = Settings::new();
|
||||
let ui = ui::TUI::initialize();
|
||||
let mut backends = Backends::new();
|
||||
backends
|
||||
.register(
|
||||
"maildir".to_string(),
|
||||
Box::new(|| Box::new(MaildirType::new(""))),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let (sender, receiver): (SyncSender<ThreadEvent>, Receiver<ThreadEvent>) =
|
||||
sync_channel(::std::mem::size_of::<ThreadEvent>());
|
||||
|
@ -55,7 +62,7 @@ fn main() {
|
|||
|
||||
let mut j = 0;
|
||||
let folder_length = set.accounts["norn"].folders.len();
|
||||
let mut account = Account::new("norn".to_string(), set.accounts["norn"].clone());
|
||||
let mut account = Account::new("norn".to_string(), set.accounts["norn"].clone(), backends);
|
||||
{
|
||||
let sender = sender.clone();
|
||||
account.watch(RefreshEventConsumer::new(Box::new(move |r| {
|
||||
|
|
|
@ -26,20 +26,6 @@ use std::io;
|
|||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MailFormat {
|
||||
Maildir,
|
||||
}
|
||||
|
||||
impl MailFormat {
|
||||
pub fn from_str(x: &str) -> MailFormat {
|
||||
match x.to_lowercase().as_ref() {
|
||||
"maildir" => MailFormat::Maildir,
|
||||
_ => panic!("Unrecognizable mail format"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct FileAccount {
|
||||
folders: String,
|
||||
|
@ -56,10 +42,17 @@ struct FileSettings {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct AccountSettings {
|
||||
pub folders: Vec<String>,
|
||||
format: MailFormat,
|
||||
format: String,
|
||||
pub sent_folder: String,
|
||||
threaded: bool,
|
||||
}
|
||||
|
||||
impl AccountSettings {
|
||||
pub fn get_format(&self) -> &str {
|
||||
&self.format
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Settings {
|
||||
pub accounts: HashMap<String, AccountSettings>,
|
||||
|
@ -126,7 +119,7 @@ impl Settings {
|
|||
id.clone(),
|
||||
AccountSettings {
|
||||
folders: folders,
|
||||
format: MailFormat::from_str(&x.format),
|
||||
format: x.format.to_lowercase(),
|
||||
sent_folder: x.sent_folder.clone(),
|
||||
threaded: x.threaded,
|
||||
},
|
||||
|
|
|
@ -39,4 +39,5 @@ extern crate bitflags;
|
|||
pub use mailbox::*;
|
||||
pub use conf::*;
|
||||
|
||||
pub use mailbox::backends::RefreshEventConsumer;
|
||||
pub use mailbox::backends::{RefreshEventConsumer, Backends};
|
||||
pub use mailbox::backends::maildir::MaildirType;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
use mailbox::*;
|
||||
use mailbox::backends::RefreshEventConsumer;
|
||||
use mailbox::backends::{RefreshEventConsumer, Backends};
|
||||
use conf::AccountSettings;
|
||||
use std::ops::{Index, IndexMut};
|
||||
#[derive(Debug)]
|
||||
|
@ -35,9 +35,8 @@ pub struct Account {
|
|||
}
|
||||
|
||||
|
||||
use mailbox::backends::maildir::MaildirType;
|
||||
impl Account {
|
||||
pub fn new(name: String, settings: AccountSettings) -> Self {
|
||||
pub fn new(name: String, settings: AccountSettings, backends: Backends) -> Self {
|
||||
eprintln!("new acc");
|
||||
let sent_folder = settings
|
||||
.folders
|
||||
|
@ -47,7 +46,7 @@ impl Account {
|
|||
for _ in 0..settings.folders.len() {
|
||||
folders.push(None);
|
||||
}
|
||||
let backend = Box::new(MaildirType::new(""));
|
||||
let backend = backends.get(settings.get_format()).unwrap();
|
||||
Account {
|
||||
name: name,
|
||||
folders: folders,
|
||||
|
@ -79,7 +78,7 @@ impl IndexMut<usize> for Account {
|
|||
let id = self.sent_folder.unwrap();
|
||||
if id == index {
|
||||
eprintln!("building sent_folder..");
|
||||
self.folders[index] = Some(Mailbox::new(&path, &None));
|
||||
self.folders[index] = Some(Mailbox::new(&path, &None, self.backend.get(&path)));
|
||||
eprintln!("Done!");
|
||||
} else {
|
||||
eprintln!(
|
||||
|
@ -99,10 +98,10 @@ impl IndexMut<usize> for Account {
|
|||
let sent_path = self.settings.folders[id].clone();
|
||||
if sent[0].is_none() {
|
||||
eprintln!("\tbuilding sent_folder..");
|
||||
sent[0] = Some(Mailbox::new(&sent_path, &None));
|
||||
sent[0] = Some(Mailbox::new(&sent_path, &None, self.backend.get(&path)));
|
||||
eprintln!("\tDone!");
|
||||
}
|
||||
cur[0] = Some(Mailbox::new(&path, &sent[0]));
|
||||
cur[0] = Some(Mailbox::new(&path, &sent[0],self.backend.get(&path)));
|
||||
eprintln!("Done!");
|
||||
}
|
||||
} else {
|
||||
|
@ -110,7 +109,7 @@ impl IndexMut<usize> for Account {
|
|||
"Now building folder {:?} without sent_folder",
|
||||
self.settings.folders[index]
|
||||
);
|
||||
self.folders[index] = Some(Mailbox::new(&path, &None));
|
||||
self.folders[index] = Some(Mailbox::new(&path, &None,self.backend.get(&path)));
|
||||
eprintln!("Done!");
|
||||
};
|
||||
}
|
||||
|
|
|
@ -120,8 +120,8 @@ pub struct MaildirType {
|
|||
|
||||
|
||||
impl MailBackend for MaildirType {
|
||||
fn get(&self) -> Result<Vec<Envelope>> {
|
||||
self.get_multicore(4)
|
||||
fn get(&self, path: &str) -> Result<Vec<Envelope>> {
|
||||
self.get_multicore(4, path)
|
||||
/*
|
||||
|
||||
MaildirType::is_valid(&self.path)?;
|
||||
|
@ -193,9 +193,9 @@ impl MaildirType {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn get_multicore(&self, cores: usize) -> Result<Vec<Envelope>> {
|
||||
MaildirType::is_valid(&self.path)?;
|
||||
let mut path = PathBuf::from(&self.path);
|
||||
pub fn get_multicore(&self, cores: usize, path: &str) -> Result<Vec<Envelope>> {
|
||||
MaildirType::is_valid(path)?;
|
||||
let mut path = PathBuf::from(path);
|
||||
path.push("cur");
|
||||
let iter = path.read_dir()?;
|
||||
let count = path.read_dir()?.count();
|
||||
|
|
|
@ -21,14 +21,51 @@
|
|||
pub mod maildir;
|
||||
|
||||
use mailbox::email::{Envelope, Flag};
|
||||
use error::Result;
|
||||
|
||||
use error::{MeliError, Result};
|
||||
use std::fmt;
|
||||
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHashMap;
|
||||
use std;
|
||||
pub struct Backends {
|
||||
map: FnvHashMap<std::string::String, Box<Fn() -> Box<MailBackend>>>,
|
||||
}
|
||||
|
||||
impl Backends {
|
||||
pub fn new() -> Self {
|
||||
Backends {
|
||||
map: FnvHashMap::with_capacity_and_hasher(1, Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, key: &str) -> Result<Box<MailBackend>> {
|
||||
if !self.map.contains_key(key) {
|
||||
return Err(MeliError::new(
|
||||
format!("{} is not a valid mail backend", key),
|
||||
));
|
||||
}
|
||||
Ok(self.map[key]())
|
||||
}
|
||||
pub fn register(&mut self, key: String, backend: Box<Fn() -> Box<MailBackend>>) -> Result<()> {
|
||||
if self.map.contains_key(&key) {
|
||||
return Err(MeliError::new(
|
||||
format!("{} is an already registered backend", key),
|
||||
));
|
||||
}
|
||||
self.map.insert(key, backend);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct RefreshEvent {
|
||||
pub folder: String,
|
||||
}
|
||||
|
||||
/// A `RefreshEventConsumer` is a boxed closure that must be used to consume a `RefreshEvent` and
|
||||
/// send it to a UI provided channel. We need this level of abstraction to provide an interface for
|
||||
/// all users of mailbox refresh events.
|
||||
pub struct RefreshEventConsumer(Box<Fn(RefreshEvent) -> ()>);
|
||||
unsafe impl Send for RefreshEventConsumer {}
|
||||
unsafe impl Sync for RefreshEventConsumer {}
|
||||
|
@ -41,9 +78,10 @@ impl RefreshEventConsumer {
|
|||
}
|
||||
}
|
||||
pub trait MailBackend: ::std::fmt::Debug {
|
||||
fn get(&self) -> Result<Vec<Envelope>>;
|
||||
fn get(&self, path: &str) -> Result<Vec<Envelope>>;
|
||||
fn watch(&self, sender:RefreshEventConsumer, folders: &[String]) -> ();
|
||||
//fn new(folders: &Vec<String>) -> Box<Self>;
|
||||
//login function
|
||||
}
|
||||
|
||||
/// A `BackendOp` manages common operations for the various mail backends. They only live for the
|
||||
|
|
|
@ -24,7 +24,6 @@ pub use self::email::*;
|
|||
/* Mail backends. Currently only maildir is supported */
|
||||
pub mod backends;
|
||||
use mailbox::backends::MailBackend;
|
||||
use mailbox::backends::maildir;
|
||||
use error::Result;
|
||||
pub mod accounts;
|
||||
pub use mailbox::accounts::Account;
|
||||
|
@ -45,12 +44,10 @@ pub struct Mailbox {
|
|||
|
||||
|
||||
impl Mailbox {
|
||||
pub fn new(path: &str, sent_folder: &Option<Result<Mailbox>>) -> Result<Mailbox> {
|
||||
let mut collection: Vec<Envelope> = maildir::MaildirType::new(path).get()?;
|
||||
pub fn new(path: &str, sent_folder: &Option<Result<Mailbox>>, collection: Result<Vec<Envelope>>) -> Result<Mailbox> {
|
||||
let mut collection: Vec<Envelope> = collection?;
|
||||
collection.sort_by(|a, b| a.get_date().cmp(&b.get_date()));
|
||||
let (threads, threaded_collection) = build_threads(&mut collection, sent_folder);
|
||||
|
||||
|
||||
Ok(Mailbox {
|
||||
path: path.to_string(),
|
||||
collection: collection,
|
||||
|
|
Loading…
Reference in New Issue