mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-25 04:20:22 +00:00
parent
811ea45610
commit
6b042f5e6a
11 changed files with 70 additions and 46 deletions
|
@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `In-Reply-To` not set properly when replying to a message [#323]
|
||||
- `Cc` missing or invalid when replying to a message [#324]
|
||||
- Notmuch backend hangs [#329]
|
||||
- Maildir e2e tests [#335]
|
||||
- JSON API for listings [#331]
|
||||
|
||||
## [0.5.8] - 2022-03-04
|
||||
|
||||
|
@ -499,3 +501,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
[#323]: https://github.com/soywod/himalaya/issues/323
|
||||
[#324]: https://github.com/soywod/himalaya/issues/324
|
||||
[#329]: https://github.com/soywod/himalaya/issues/329
|
||||
[#331]: https://github.com/soywod/himalaya/issues/331
|
||||
[#335]: https://github.com/soywod/himalaya/issues/335
|
||||
|
|
|
@ -15,13 +15,16 @@ use super::{ImapFlag, ImapFlags};
|
|||
|
||||
/// Represents a list of IMAP envelopes.
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
pub struct ImapEnvelopes(pub Vec<ImapEnvelope>);
|
||||
pub struct ImapEnvelopes {
|
||||
#[serde(rename = "response")]
|
||||
pub envelopes: Vec<ImapEnvelope>,
|
||||
}
|
||||
|
||||
impl Deref for ImapEnvelopes {
|
||||
type Target = Vec<ImapEnvelope>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.envelopes
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +102,7 @@ impl TryFrom<RawImapEnvelopes> for ImapEnvelopes {
|
|||
for raw_envelope in raw_envelopes.iter().rev() {
|
||||
envelopes.push(ImapEnvelope::try_from(raw_envelope).context("cannot parse envelope")?);
|
||||
}
|
||||
Ok(Self(envelopes))
|
||||
Ok(Self { envelopes })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//! to the mailbox.
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use std::fmt::{self, Display};
|
||||
use std::ops::Deref;
|
||||
|
||||
|
@ -16,14 +17,17 @@ use crate::{
|
|||
use super::ImapMboxAttrs;
|
||||
|
||||
/// Represents a list of IMAP mailboxes.
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
pub struct ImapMboxes(pub Vec<ImapMbox>);
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
pub struct ImapMboxes {
|
||||
#[serde(rename = "response")]
|
||||
pub mboxes: Vec<ImapMbox>,
|
||||
}
|
||||
|
||||
impl Deref for ImapMboxes {
|
||||
type Target = Vec<ImapMbox>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.mboxes
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +134,9 @@ pub type RawImapMboxes = imap::types::ZeroCopy<Vec<RawImapMbox>>;
|
|||
|
||||
impl<'a> From<RawImapMboxes> for ImapMboxes {
|
||||
fn from(raw_mboxes: RawImapMboxes) -> Self {
|
||||
Self(raw_mboxes.iter().map(ImapMbox::from).collect())
|
||||
Self {
|
||||
mboxes: raw_mboxes.iter().map(ImapMbox::from).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ impl<'a> Backend<'a> for MaildirBackend<'a> {
|
|||
envelopes.sort_by(|a, b| b.date.partial_cmp(&a.date).unwrap());
|
||||
|
||||
// Applies pagination boundaries.
|
||||
envelopes.0 = envelopes[page_begin..page_end].to_owned();
|
||||
envelopes.envelopes = envelopes[page_begin..page_end].to_owned();
|
||||
|
||||
// Appends envelopes hash to the id mapper cache file and
|
||||
// calculates the new short hash length. The short hash length
|
||||
|
|
|
@ -20,19 +20,22 @@ use crate::{
|
|||
|
||||
/// Represents a list of envelopes.
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
pub struct MaildirEnvelopes(pub Vec<MaildirEnvelope>);
|
||||
pub struct MaildirEnvelopes {
|
||||
#[serde(rename = "response")]
|
||||
pub envelopes: Vec<MaildirEnvelope>,
|
||||
}
|
||||
|
||||
impl Deref for MaildirEnvelopes {
|
||||
type Target = Vec<MaildirEnvelope>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.envelopes
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for MaildirEnvelopes {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
&mut self.envelopes
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +117,7 @@ impl<'a> TryFrom<RawMaildirEnvelopes> for MaildirEnvelopes {
|
|||
envelopes.push(envelope);
|
||||
}
|
||||
|
||||
Ok(MaildirEnvelopes(envelopes))
|
||||
Ok(MaildirEnvelopes { envelopes })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,16 @@ use crate::{
|
|||
|
||||
/// Represents a list of Maildir mailboxes.
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
pub struct MaildirMboxes(pub Vec<MaildirMbox>);
|
||||
pub struct MaildirMboxes {
|
||||
#[serde(rename = "response")]
|
||||
pub mboxes: Vec<MaildirMbox>,
|
||||
}
|
||||
|
||||
impl Deref for MaildirMboxes {
|
||||
type Target = Vec<MaildirMbox>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.mboxes
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +116,7 @@ impl TryFrom<RawMaildirMboxes> for MaildirMboxes {
|
|||
for entry in mail_entries {
|
||||
mboxes.push(entry?.try_into()?);
|
||||
}
|
||||
Ok(MaildirMboxes(mboxes))
|
||||
Ok(MaildirMboxes { mboxes })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ impl<'a> NotmuchBackend<'a> {
|
|||
envelopes.sort_by(|a, b| b.date.partial_cmp(&a.date).unwrap());
|
||||
|
||||
// Applies pagination boundaries.
|
||||
envelopes.0 = envelopes[page_begin..page_end].to_owned();
|
||||
envelopes.envelopes = envelopes[page_begin..page_end].to_owned();
|
||||
|
||||
// Appends envelopes hash to the id mapper cache file and
|
||||
// calculates the new short hash length. The short hash length
|
||||
|
@ -118,17 +118,17 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
|||
fn get_mboxes(&mut self) -> Result<Box<dyn Mboxes>> {
|
||||
info!(">> get notmuch virtual mailboxes");
|
||||
|
||||
let mut virt_mboxes: Vec<_> = self
|
||||
let mut mboxes: Vec<_> = self
|
||||
.account_config
|
||||
.mailboxes
|
||||
.iter()
|
||||
.map(|(k, v)| NotmuchMbox::new(k, v))
|
||||
.collect();
|
||||
trace!("virtual mailboxes: {:?}", virt_mboxes);
|
||||
virt_mboxes.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
|
||||
trace!("virtual mailboxes: {:?}", mboxes);
|
||||
mboxes.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
|
||||
|
||||
info!("<< get notmuch virtual mailboxes");
|
||||
Ok(Box::new(NotmuchMboxes(virt_mboxes)))
|
||||
Ok(Box::new(NotmuchMboxes { mboxes }))
|
||||
}
|
||||
|
||||
fn del_mbox(&mut self, _mbox: &str) -> Result<()> {
|
||||
|
@ -202,7 +202,7 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
|||
// Adds the message to the maildir folder and gets its hash.
|
||||
let hash = self
|
||||
.mdir
|
||||
.add_msg("inbox", msg, "seen")
|
||||
.add_msg("", msg, "seen")
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"cannot add notmuch message to maildir {:?}",
|
||||
|
|
|
@ -19,19 +19,22 @@ use crate::{
|
|||
|
||||
/// Represents a list of envelopes.
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
pub struct NotmuchEnvelopes(pub Vec<NotmuchEnvelope>);
|
||||
pub struct NotmuchEnvelopes {
|
||||
#[serde(rename = "response")]
|
||||
pub envelopes: Vec<NotmuchEnvelope>,
|
||||
}
|
||||
|
||||
impl Deref for NotmuchEnvelopes {
|
||||
type Target = Vec<NotmuchEnvelope>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.envelopes
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for NotmuchEnvelopes {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
&mut self.envelopes
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +110,7 @@ impl<'a> TryFrom<RawNotmuchEnvelopes> for NotmuchEnvelopes {
|
|||
.context("cannot parse notmuch mail entry")?;
|
||||
envelopes.push(envelope);
|
||||
}
|
||||
Ok(NotmuchEnvelopes(envelopes))
|
||||
Ok(NotmuchEnvelopes { envelopes })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,16 @@ use crate::{
|
|||
|
||||
/// Represents a list of Notmuch mailboxes.
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
pub struct NotmuchMboxes(pub Vec<NotmuchMbox>);
|
||||
pub struct NotmuchMboxes {
|
||||
#[serde(rename = "response")]
|
||||
pub mboxes: Vec<NotmuchMbox>,
|
||||
}
|
||||
|
||||
impl Deref for NotmuchMboxes {
|
||||
type Target = Vec<NotmuchMbox>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.mboxes
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,21 +115,23 @@ mod tests {
|
|||
unimplemented!();
|
||||
}
|
||||
fn get_mboxes(&mut self) -> Result<Box<dyn Mboxes>> {
|
||||
Ok(Box::new(ImapMboxes(vec![
|
||||
ImapMbox {
|
||||
delim: "/".into(),
|
||||
name: "INBOX".into(),
|
||||
attrs: ImapMboxAttrs(vec![ImapMboxAttr::NoSelect]),
|
||||
},
|
||||
ImapMbox {
|
||||
delim: "/".into(),
|
||||
name: "Sent".into(),
|
||||
attrs: ImapMboxAttrs(vec![
|
||||
ImapMboxAttr::NoInferiors,
|
||||
ImapMboxAttr::Custom("HasNoChildren".into()),
|
||||
]),
|
||||
},
|
||||
])))
|
||||
Ok(Box::new(ImapMboxes {
|
||||
mboxes: vec![
|
||||
ImapMbox {
|
||||
delim: "/".into(),
|
||||
name: "INBOX".into(),
|
||||
attrs: ImapMboxAttrs(vec![ImapMboxAttr::NoSelect]),
|
||||
},
|
||||
ImapMbox {
|
||||
delim: "/".into(),
|
||||
name: "Sent".into(),
|
||||
attrs: ImapMboxAttrs(vec![
|
||||
ImapMboxAttr::NoInferiors,
|
||||
ImapMboxAttr::Custom("HasNoChildren".into()),
|
||||
]),
|
||||
},
|
||||
],
|
||||
}))
|
||||
}
|
||||
fn del_mbox(&mut self, _: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
|
|
|
@ -19,10 +19,7 @@ fn test_maildir_backend() {
|
|||
|
||||
// configure accounts
|
||||
let account_config = AccountConfig {
|
||||
mailboxes: HashMap::from_iter([
|
||||
("inbox".into(), "INBOX".into()),
|
||||
("subdir".into(), "Subdir".into()),
|
||||
]),
|
||||
mailboxes: HashMap::from_iter([("subdir".into(), "Subdir".into())]),
|
||||
..AccountConfig::default()
|
||||
};
|
||||
let mdir_config = MaildirBackendConfig {
|
||||
|
|
Loading…
Reference in a new issue