mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-24 20:10:23 +00:00
init notmuch backend
This commit is contained in:
parent
bd15e7d979
commit
e4aa569458
8 changed files with 399 additions and 2 deletions
81
Cargo.lock
generated
81
Cargo.lock
generated
|
@ -153,7 +153,7 @@ dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"strsim",
|
"strsim 0.8.0",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
@ -183,6 +183,41 @@ version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim 0.9.3",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-next"
|
name = "dirs-next"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
@ -281,6 +316,27 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "from_variants"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "221a1eb1a3c98980bc1b740f462b3dcf73f4e371cda294986bac72497995a4e3"
|
||||||
|
dependencies = [
|
||||||
|
"from_variants_impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "from_variants_impl"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e08079fa3c89edec9160ceaa9e7172785468c26c053d12924cce0d5a55c241a"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "funty"
|
name = "funty"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -397,6 +453,7 @@ dependencies = [
|
||||||
"maildir",
|
"maildir",
|
||||||
"mailparse",
|
"mailparse",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
|
"notmuch",
|
||||||
"regex",
|
"regex",
|
||||||
"rfc2047-decoder",
|
"rfc2047-decoder",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -457,6 +514,12 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -732,6 +795,16 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "notmuch"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca0941fd9af5b8529e3d42494f56efafb909b76190a7a454cde9d6e397390cf9"
|
||||||
|
dependencies = [
|
||||||
|
"from_variants",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
|
@ -1241,6 +1314,12 @@ version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.81"
|
version = "1.0.81"
|
||||||
|
|
|
@ -32,6 +32,7 @@ log = "0.4.14"
|
||||||
maildir = "0.6.0"
|
maildir = "0.6.0"
|
||||||
mailparse = "0.13.6"
|
mailparse = "0.13.6"
|
||||||
native-tls = "0.2.8"
|
native-tls = "0.2.8"
|
||||||
|
notmuch = "0.7.1"
|
||||||
regex = "1.5.4"
|
regex = "1.5.4"
|
||||||
rfc2047-decoder = "0.1.2"
|
rfc2047-decoder = "0.1.2"
|
||||||
serde = { version = "1.0.118", features = ["derive"] }
|
serde = { version = "1.0.118", features = ["derive"] }
|
||||||
|
|
101
src/backends/notmuch/notmuch_backend.rs
Normal file
101
src/backends/notmuch/notmuch_backend.rs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
backends::Backend,
|
||||||
|
config::{AccountConfig, NotmuchBackendConfig},
|
||||||
|
mbox::Mboxes,
|
||||||
|
msg::{Envelopes, Msg},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::NotmuchEnvelopes;
|
||||||
|
|
||||||
|
pub struct NotmuchBackend<'a> {
|
||||||
|
account_config: &'a AccountConfig,
|
||||||
|
db: notmuch::Database,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> NotmuchBackend<'a> {
|
||||||
|
pub fn new(
|
||||||
|
account_config: &'a AccountConfig,
|
||||||
|
notmuch_config: &'a NotmuchBackendConfig,
|
||||||
|
) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
account_config,
|
||||||
|
db: notmuch::Database::open(
|
||||||
|
notmuch_config.notmuch_database_dir.clone(),
|
||||||
|
notmuch::DatabaseMode::ReadWrite,
|
||||||
|
)
|
||||||
|
.context(format!(
|
||||||
|
"cannot open notmuch database at {:?}",
|
||||||
|
notmuch_config.notmuch_database_dir
|
||||||
|
))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
||||||
|
fn add_mbox(&mut self, mdir: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mboxes(&mut self) -> Result<Box<dyn Mboxes>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn del_mbox(&mut self, mdir: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_envelopes(
|
||||||
|
&mut self,
|
||||||
|
mdir: &str,
|
||||||
|
_sort: &str,
|
||||||
|
filter: &str,
|
||||||
|
page_size: usize,
|
||||||
|
page: usize,
|
||||||
|
) -> Result<Box<dyn Envelopes>> {
|
||||||
|
let query = self
|
||||||
|
.db
|
||||||
|
.create_query(filter)
|
||||||
|
.context("cannot create query")?;
|
||||||
|
let msgs: NotmuchEnvelopes = query
|
||||||
|
.search_messages()
|
||||||
|
.context("cannot get messages")?
|
||||||
|
.try_into()?;
|
||||||
|
Ok(Box::new(msgs))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_msg(&mut self, mdir: &str, msg: &[u8], flags: &str) -> Result<Box<dyn ToString>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_msg(&mut self, mdir: &str, id: &str) -> Result<Msg> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_msg(&mut self, mdir_src: &str, mdir_dst: &str, id: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_msg(&mut self, mdir_src: &str, mdir_dst: &str, id: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn del_msg(&mut self, mdir: &str, id: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_flags(&mut self, mdir: &str, id: &str, flags_str: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_flags(&mut self, mdir: &str, id: &str, flags_str: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn del_flags(&mut self, mdir: &str, id: &str, flags_str: &str) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
172
src/backends/notmuch/notmuch_envelope.rs
Normal file
172
src/backends/notmuch/notmuch_envelope.rs
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
//! Notmuch mailbox module.
|
||||||
|
//!
|
||||||
|
//! This module provides Notmuch types and conversion utilities
|
||||||
|
//! related to the envelope
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Context, Error, Result};
|
||||||
|
use chrono::DateTime;
|
||||||
|
use log::{info, trace};
|
||||||
|
use std::{
|
||||||
|
convert::{TryFrom, TryInto},
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
msg::{from_slice_to_addrs, Addr},
|
||||||
|
output::{PrintTable, PrintTableOpts, WriteColor},
|
||||||
|
ui::{Cell, Row, Table},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a list of envelopes.
|
||||||
|
#[derive(Debug, Default, serde::Serialize)]
|
||||||
|
pub struct NotmuchEnvelopes(pub Vec<NotmuchEnvelope>);
|
||||||
|
|
||||||
|
impl Deref for NotmuchEnvelopes {
|
||||||
|
type Target = Vec<NotmuchEnvelope>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for NotmuchEnvelopes {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrintTable for NotmuchEnvelopes {
|
||||||
|
fn print_table(&self, writter: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> {
|
||||||
|
writeln!(writter)?;
|
||||||
|
Table::print(writter, self, opts)?;
|
||||||
|
writeln!(writter)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the envelope. The envelope is just a message subset,
|
||||||
|
/// and is mostly used for listings.
|
||||||
|
#[derive(Debug, Default, Clone, serde::Serialize)]
|
||||||
|
pub struct NotmuchEnvelope {
|
||||||
|
/// Represents the id of the message.
|
||||||
|
pub id: String,
|
||||||
|
|
||||||
|
/// Represents the tags of the message.
|
||||||
|
pub flags: Vec<String>,
|
||||||
|
|
||||||
|
/// Represents the subject of the message.
|
||||||
|
pub subject: String,
|
||||||
|
|
||||||
|
/// Represents the first sender of the message.
|
||||||
|
pub sender: String,
|
||||||
|
|
||||||
|
/// Represents the date of the message.
|
||||||
|
pub date: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Table for NotmuchEnvelope {
|
||||||
|
fn head() -> Row {
|
||||||
|
Row::new()
|
||||||
|
.cell(Cell::new("ID").bold().underline().white())
|
||||||
|
.cell(Cell::new("FLAGS").bold().underline().white())
|
||||||
|
.cell(Cell::new("SUBJECT").shrinkable().bold().underline().white())
|
||||||
|
.cell(Cell::new("SENDER").bold().underline().white())
|
||||||
|
.cell(Cell::new("DATE").bold().underline().white())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn row(&self) -> Row {
|
||||||
|
let id = self.id.to_string();
|
||||||
|
let unseen = !self.flags.contains(&String::from("unread"));
|
||||||
|
let flags = String::new();
|
||||||
|
let subject = &self.subject;
|
||||||
|
let sender = &self.sender;
|
||||||
|
let date = &self.date;
|
||||||
|
Row::new()
|
||||||
|
.cell(Cell::new(id).bold_if(unseen).red())
|
||||||
|
.cell(Cell::new(flags).bold_if(unseen).white())
|
||||||
|
.cell(Cell::new(subject).shrinkable().bold_if(unseen).green())
|
||||||
|
.cell(Cell::new(sender).bold_if(unseen).blue())
|
||||||
|
.cell(Cell::new(date).bold_if(unseen).yellow())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a list of raw envelopees returned by the `notmuch` crate.
|
||||||
|
pub type RawNotmuchEnvelopes = notmuch::Messages;
|
||||||
|
|
||||||
|
impl<'a> TryFrom<RawNotmuchEnvelopes> for NotmuchEnvelopes {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(raw_envelopes: RawNotmuchEnvelopes) -> Result<Self, Self::Error> {
|
||||||
|
let mut envelopes = vec![];
|
||||||
|
for raw_envelope in raw_envelopes {
|
||||||
|
let envelope: NotmuchEnvelope = raw_envelope
|
||||||
|
.try_into()
|
||||||
|
.context("cannot parse notmuch mail entry")?;
|
||||||
|
envelopes.push(envelope);
|
||||||
|
}
|
||||||
|
Ok(NotmuchEnvelopes(envelopes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the raw envelope returned by the `notmuch` crate.
|
||||||
|
pub type RawNotmuchEnvelope = notmuch::Message;
|
||||||
|
|
||||||
|
impl<'a> TryFrom<RawNotmuchEnvelope> for NotmuchEnvelope {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(raw_envelope: RawNotmuchEnvelope) -> Result<Self, Self::Error> {
|
||||||
|
info!("begin: try building envelope from notmuch parsed mail");
|
||||||
|
|
||||||
|
let id = raw_envelope.id().trim().to_string();
|
||||||
|
let subject = raw_envelope
|
||||||
|
.header("subject")
|
||||||
|
.context("cannot get header \"Subject\" from notmuch message")?
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string();
|
||||||
|
let sender = raw_envelope
|
||||||
|
.header("from")
|
||||||
|
.context("cannot get header \"From\" from notmuch message")?
|
||||||
|
.ok_or_else(|| anyhow!("cannot parse sender from notmuch message {:?}", id))?
|
||||||
|
.to_string();
|
||||||
|
let sender = from_slice_to_addrs(sender)?
|
||||||
|
.and_then(|senders| {
|
||||||
|
if senders.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(senders)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|senders| match &senders[0] {
|
||||||
|
Addr::Single(mailparse::SingleInfo { display_name, addr }) => {
|
||||||
|
display_name.as_ref().unwrap_or_else(|| addr).to_owned()
|
||||||
|
}
|
||||||
|
Addr::Group(mailparse::GroupInfo { group_name, .. }) => group_name.to_owned(),
|
||||||
|
})
|
||||||
|
.ok_or_else(|| anyhow!("cannot find sender"))?;
|
||||||
|
let date = raw_envelope
|
||||||
|
.header("date")
|
||||||
|
.context("cannot get header \"Date\" from notmuch message")?
|
||||||
|
.ok_or_else(|| anyhow!("cannot parse date of notmuch message {:?}", id))?
|
||||||
|
.to_string();
|
||||||
|
let date =
|
||||||
|
DateTime::parse_from_rfc2822(date.split_at(date.find(" (").unwrap_or(date.len())).0)
|
||||||
|
.context(format!(
|
||||||
|
"cannot parse message date {:?} of notmuch message {:?}",
|
||||||
|
date, id
|
||||||
|
))?
|
||||||
|
.naive_local()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let envelope = Self {
|
||||||
|
id,
|
||||||
|
flags: raw_envelope.tags().collect(),
|
||||||
|
subject,
|
||||||
|
sender,
|
||||||
|
date,
|
||||||
|
};
|
||||||
|
trace!("envelope: {:?}", envelope);
|
||||||
|
|
||||||
|
info!("end: try building envelope from notmuch parsed mail");
|
||||||
|
Ok(envelope)
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,6 +73,9 @@ impl<'a> AccountConfig {
|
||||||
DeserializedAccountConfig::Maildir(account) => {
|
DeserializedAccountConfig::Maildir(account) => {
|
||||||
account.default.unwrap_or_default()
|
account.default.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
DeserializedAccountConfig::Notmuch(account) => {
|
||||||
|
account.default.unwrap_or_default()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.map(|(name, account)| (name.to_owned(), account))
|
.map(|(name, account)| (name.to_owned(), account))
|
||||||
.ok_or_else(|| anyhow!("cannot find default account")),
|
.ok_or_else(|| anyhow!("cannot find default account")),
|
||||||
|
@ -194,6 +197,13 @@ impl<'a> AccountConfig {
|
||||||
maildir_dir: shellexpand::full(&config.maildir_dir)?.to_string().into(),
|
maildir_dir: shellexpand::full(&config.maildir_dir)?.to_string().into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
DeserializedAccountConfig::Notmuch(config) => {
|
||||||
|
BackendConfig::Notmuch(NotmuchBackendConfig {
|
||||||
|
notmuch_database_dir: shellexpand::full(&config.notmuch_database_dir)?
|
||||||
|
.to_string()
|
||||||
|
.into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
trace!("backend config: {:?}", backend_config);
|
trace!("backend config: {:?}", backend_config);
|
||||||
|
|
||||||
|
@ -321,6 +331,7 @@ impl<'a> AccountConfig {
|
||||||
pub enum BackendConfig {
|
pub enum BackendConfig {
|
||||||
Imap(ImapBackendConfig),
|
Imap(ImapBackendConfig),
|
||||||
Maildir(MaildirBackendConfig),
|
Maildir(MaildirBackendConfig),
|
||||||
|
Notmuch(NotmuchBackendConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the IMAP backend.
|
/// Represents the IMAP backend.
|
||||||
|
@ -358,6 +369,13 @@ pub struct MaildirBackendConfig {
|
||||||
pub maildir_dir: PathBuf,
|
pub maildir_dir: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the Notmuch backend.
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct NotmuchBackendConfig {
|
||||||
|
/// Represents the Notmuch database path.
|
||||||
|
pub notmuch_database_dir: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub trait ToDeserializedBaseAccountConfig {
|
||||||
pub enum DeserializedAccountConfig {
|
pub enum DeserializedAccountConfig {
|
||||||
Imap(DeserializedImapAccountConfig),
|
Imap(DeserializedImapAccountConfig),
|
||||||
Maildir(DeserializedMaildirAccountConfig),
|
Maildir(DeserializedMaildirAccountConfig),
|
||||||
|
Notmuch(DeserializedNotmuchAccountConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToDeserializedBaseAccountConfig for DeserializedAccountConfig {
|
impl ToDeserializedBaseAccountConfig for DeserializedAccountConfig {
|
||||||
|
@ -18,6 +19,7 @@ impl ToDeserializedBaseAccountConfig for DeserializedAccountConfig {
|
||||||
match self {
|
match self {
|
||||||
Self::Imap(config) => config.to_base(),
|
Self::Imap(config) => config.to_base(),
|
||||||
Self::Maildir(config) => config.to_base(),
|
Self::Maildir(config) => config.to_base(),
|
||||||
|
Self::Notmuch(config) => config.to_base(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,3 +124,8 @@ make_account_config!(
|
||||||
);
|
);
|
||||||
|
|
||||||
make_account_config!(DeserializedMaildirAccountConfig, maildir_dir: String);
|
make_account_config!(DeserializedMaildirAccountConfig, maildir_dir: String);
|
||||||
|
|
||||||
|
make_account_config!(
|
||||||
|
DeserializedNotmuchAccountConfig,
|
||||||
|
notmuch_database_dir: String
|
||||||
|
);
|
||||||
|
|
|
@ -75,6 +75,15 @@ pub mod backends {
|
||||||
pub mod maildir_flag;
|
pub mod maildir_flag;
|
||||||
pub use maildir_flag::*;
|
pub use maildir_flag::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::notmuch::*;
|
||||||
|
pub mod notmuch {
|
||||||
|
pub mod notmuch_backend;
|
||||||
|
pub use notmuch_backend::*;
|
||||||
|
|
||||||
|
pub mod notmuch_envelope;
|
||||||
|
pub use notmuch_envelope::*;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod smtp {
|
pub mod smtp {
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -3,7 +3,7 @@ use std::{convert::TryFrom, env};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use himalaya::{
|
use himalaya::{
|
||||||
backends::{imap_arg, imap_handler, Backend, ImapBackend, MaildirBackend},
|
backends::{imap_arg, imap_handler, Backend, ImapBackend, MaildirBackend, NotmuchBackend},
|
||||||
compl::{compl_arg, compl_handler},
|
compl::{compl_arg, compl_handler},
|
||||||
config::{account_args, config_args, AccountConfig, BackendConfig, DeserializedConfig},
|
config::{account_args, config_args, AccountConfig, BackendConfig, DeserializedConfig},
|
||||||
mbox::{mbox_arg, mbox_handler},
|
mbox::{mbox_arg, mbox_handler},
|
||||||
|
@ -45,6 +45,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
let mut imap;
|
let mut imap;
|
||||||
let mut maildir;
|
let mut maildir;
|
||||||
|
let mut notmuch;
|
||||||
let backend: Box<&mut dyn Backend> = match backend_config {
|
let backend: Box<&mut dyn Backend> = match backend_config {
|
||||||
BackendConfig::Imap(ref imap_config) => {
|
BackendConfig::Imap(ref imap_config) => {
|
||||||
imap = ImapBackend::new(&account_config, imap_config);
|
imap = ImapBackend::new(&account_config, imap_config);
|
||||||
|
@ -54,6 +55,10 @@ fn main() -> Result<()> {
|
||||||
maildir = MaildirBackend::new(&account_config, maildir_config);
|
maildir = MaildirBackend::new(&account_config, maildir_config);
|
||||||
Box::new(&mut maildir)
|
Box::new(&mut maildir)
|
||||||
}
|
}
|
||||||
|
BackendConfig::Notmuch(ref notmuch_config) => {
|
||||||
|
notmuch = NotmuchBackend::new(&account_config, notmuch_config)?;
|
||||||
|
Box::new(&mut notmuch)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return msg_handler::mailto(&url, &account_config, &mut printer, backend, &mut smtp);
|
return msg_handler::mailto(&url, &account_config, &mut printer, backend, &mut smtp);
|
||||||
|
@ -81,6 +86,7 @@ fn main() -> Result<()> {
|
||||||
let mut printer = StdoutPrinter::try_from(m.value_of("output"))?;
|
let mut printer = StdoutPrinter::try_from(m.value_of("output"))?;
|
||||||
let mut imap;
|
let mut imap;
|
||||||
let mut maildir;
|
let mut maildir;
|
||||||
|
let mut notmuch;
|
||||||
let backend: Box<&mut dyn Backend> = match backend_config {
|
let backend: Box<&mut dyn Backend> = match backend_config {
|
||||||
BackendConfig::Imap(ref imap_config) => {
|
BackendConfig::Imap(ref imap_config) => {
|
||||||
imap = ImapBackend::new(&account_config, imap_config);
|
imap = ImapBackend::new(&account_config, imap_config);
|
||||||
|
@ -90,6 +96,10 @@ fn main() -> Result<()> {
|
||||||
maildir = MaildirBackend::new(&account_config, maildir_config);
|
maildir = MaildirBackend::new(&account_config, maildir_config);
|
||||||
Box::new(&mut maildir)
|
Box::new(&mut maildir)
|
||||||
}
|
}
|
||||||
|
BackendConfig::Notmuch(ref notmuch_config) => {
|
||||||
|
notmuch = NotmuchBackend::new(&account_config, notmuch_config)?;
|
||||||
|
Box::new(&mut notmuch)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut smtp = LettreService::from(&account_config);
|
let mut smtp = LettreService::from(&account_config);
|
||||||
|
|
Loading…
Reference in a new issue