diff --git a/CHANGELOG.md b/CHANGELOG.md index db714a6..76a52aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/backends/imap/imap_envelope.rs b/src/backends/imap/imap_envelope.rs index 323df8f..d087eb1 100644 --- a/src/backends/imap/imap_envelope.rs +++ b/src/backends/imap/imap_envelope.rs @@ -15,13 +15,16 @@ use super::{ImapFlag, ImapFlags}; /// Represents a list of IMAP envelopes. #[derive(Debug, Default, serde::Serialize)] -pub struct ImapEnvelopes(pub Vec); +pub struct ImapEnvelopes { + #[serde(rename = "response")] + pub envelopes: Vec, +} impl Deref for ImapEnvelopes { type Target = Vec; fn deref(&self) -> &Self::Target { - &self.0 + &self.envelopes } } @@ -99,7 +102,7 @@ impl TryFrom 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 }) } } diff --git a/src/backends/imap/imap_mbox.rs b/src/backends/imap/imap_mbox.rs index 054c496..223ab6c 100644 --- a/src/backends/imap/imap_mbox.rs +++ b/src/backends/imap/imap_mbox.rs @@ -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); +#[derive(Debug, Default, Serialize)] +pub struct ImapMboxes { + #[serde(rename = "response")] + pub mboxes: Vec, +} impl Deref for ImapMboxes { type Target = Vec; fn deref(&self) -> &Self::Target { - &self.0 + &self.mboxes } } @@ -130,7 +134,9 @@ pub type RawImapMboxes = imap::types::ZeroCopy>; impl<'a> From 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(), + } } } diff --git a/src/backends/maildir/maildir_backend.rs b/src/backends/maildir/maildir_backend.rs index a52dd13..a2e85a5 100644 --- a/src/backends/maildir/maildir_backend.rs +++ b/src/backends/maildir/maildir_backend.rs @@ -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 diff --git a/src/backends/maildir/maildir_envelope.rs b/src/backends/maildir/maildir_envelope.rs index 17e064c..10cb3be 100644 --- a/src/backends/maildir/maildir_envelope.rs +++ b/src/backends/maildir/maildir_envelope.rs @@ -20,19 +20,22 @@ use crate::{ /// Represents a list of envelopes. #[derive(Debug, Default, serde::Serialize)] -pub struct MaildirEnvelopes(pub Vec); +pub struct MaildirEnvelopes { + #[serde(rename = "response")] + pub envelopes: Vec, +} impl Deref for MaildirEnvelopes { type Target = Vec; 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 for MaildirEnvelopes { envelopes.push(envelope); } - Ok(MaildirEnvelopes(envelopes)) + Ok(MaildirEnvelopes { envelopes }) } } diff --git a/src/backends/maildir/maildir_mbox.rs b/src/backends/maildir/maildir_mbox.rs index 946d284..3f2ec2f 100644 --- a/src/backends/maildir/maildir_mbox.rs +++ b/src/backends/maildir/maildir_mbox.rs @@ -19,13 +19,16 @@ use crate::{ /// Represents a list of Maildir mailboxes. #[derive(Debug, Default, serde::Serialize)] -pub struct MaildirMboxes(pub Vec); +pub struct MaildirMboxes { + #[serde(rename = "response")] + pub mboxes: Vec, +} impl Deref for MaildirMboxes { type Target = Vec; fn deref(&self) -> &Self::Target { - &self.0 + &self.mboxes } } @@ -113,7 +116,7 @@ impl TryFrom for MaildirMboxes { for entry in mail_entries { mboxes.push(entry?.try_into()?); } - Ok(MaildirMboxes(mboxes)) + Ok(MaildirMboxes { mboxes }) } } diff --git a/src/backends/notmuch/notmuch_backend.rs b/src/backends/notmuch/notmuch_backend.rs index 416e1c0..37e559a 100644 --- a/src/backends/notmuch/notmuch_backend.rs +++ b/src/backends/notmuch/notmuch_backend.rs @@ -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> { 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 {:?}", diff --git a/src/backends/notmuch/notmuch_envelope.rs b/src/backends/notmuch/notmuch_envelope.rs index f7efc45..626d949 100644 --- a/src/backends/notmuch/notmuch_envelope.rs +++ b/src/backends/notmuch/notmuch_envelope.rs @@ -19,19 +19,22 @@ use crate::{ /// Represents a list of envelopes. #[derive(Debug, Default, serde::Serialize)] -pub struct NotmuchEnvelopes(pub Vec); +pub struct NotmuchEnvelopes { + #[serde(rename = "response")] + pub envelopes: Vec, +} impl Deref for NotmuchEnvelopes { type Target = Vec; 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 for NotmuchEnvelopes { .context("cannot parse notmuch mail entry")?; envelopes.push(envelope); } - Ok(NotmuchEnvelopes(envelopes)) + Ok(NotmuchEnvelopes { envelopes }) } } diff --git a/src/backends/notmuch/notmuch_mbox.rs b/src/backends/notmuch/notmuch_mbox.rs index 47a6e40..2fe1262 100644 --- a/src/backends/notmuch/notmuch_mbox.rs +++ b/src/backends/notmuch/notmuch_mbox.rs @@ -17,13 +17,16 @@ use crate::{ /// Represents a list of Notmuch mailboxes. #[derive(Debug, Default, serde::Serialize)] -pub struct NotmuchMboxes(pub Vec); +pub struct NotmuchMboxes { + #[serde(rename = "response")] + pub mboxes: Vec, +} impl Deref for NotmuchMboxes { type Target = Vec; fn deref(&self) -> &Self::Target { - &self.0 + &self.mboxes } } diff --git a/src/mbox/mbox_handlers.rs b/src/mbox/mbox_handlers.rs index 44881e3..4a110e9 100644 --- a/src/mbox/mbox_handlers.rs +++ b/src/mbox/mbox_handlers.rs @@ -115,21 +115,23 @@ mod tests { unimplemented!(); } fn get_mboxes(&mut self) -> Result> { - 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!(); diff --git a/tests/test_maildir_backend.rs b/tests/test_maildir_backend.rs index d998789..11eaa52 100644 --- a/tests/test_maildir_backend.rs +++ b/tests/test_maildir_backend.rs @@ -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 {