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