fix sort command not found (#308)

This commit is contained in:
Clément DOUIN 2022-02-25 21:21:48 +01:00
parent e4aa569458
commit 34ab0f4fa5
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
6 changed files with 105 additions and 31 deletions

View file

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Build failure due to `imap` version [#303]
- No tilde expansion in `maildir-dir` [#305]
- Unknown command SORT [#308]
## [0.5.6] - 2022-02-22
@ -440,3 +441,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#289]: https://github.com/soywod/himalaya/issues/289
[#303]: https://github.com/soywod/himalaya/issues/303
[#305]: https://github.com/soywod/himalaya/issues/305
[#308]: https://github.com/soywod/himalaya/issues/308

View file

@ -21,8 +21,14 @@ pub trait Backend<'a> {
fn get_envelopes(
&mut self,
mbox: &str,
page_size: usize,
page: usize,
) -> Result<Box<dyn Envelopes>>;
fn find_envelopes(
&mut self,
mbox: &str,
query: &str,
sort: &str,
filter: &str,
page_size: usize,
page: usize,
) -> Result<Box<dyn Envelopes>>;

View file

@ -229,8 +229,42 @@ impl<'a> Backend<'a> for ImapBackend<'a> {
fn get_envelopes(
&mut self,
mbox: &str,
page_size: usize,
page: usize,
) -> Result<Box<dyn Envelopes>> {
let last_seq = self
.sess()?
.select(mbox)
.context(format!("cannot select mailbox {:?}", mbox))?
.exists as usize;
debug!("last sequence number: {:?}", last_seq);
if last_seq == 0 {
return Ok(Box::new(ImapEnvelopes::default()));
}
let range = if page_size > 0 {
let cursor = page * page_size;
let begin = 1.max(last_seq - cursor);
let end = begin - begin.min(page_size) + 1;
format!("{}:{}", end, begin)
} else {
String::from("1:*")
};
debug!("range: {:?}", range);
let fetches = self
.sess()?
.fetch(&range, "(ENVELOPE FLAGS INTERNALDATE)")
.context(format!("cannot fetch messages within range {:?}", range))?;
let envelopes: ImapEnvelopes = fetches.try_into()?;
Ok(Box::new(envelopes))
}
fn find_envelopes(
&mut self,
mbox: &str,
query: &str,
sort: &str,
filter: &str,
page_size: usize,
page: usize,
) -> Result<Box<dyn Envelopes>> {
@ -239,24 +273,36 @@ impl<'a> Backend<'a> for ImapBackend<'a> {
.select(mbox)
.context(format!("cannot select mailbox {:?}", mbox))?
.exists;
debug!("last sequence number: {:?}", last_seq);
if last_seq == 0 {
return Ok(Box::new(ImapEnvelopes::default()));
}
let sort: SortCriteria = sort.try_into()?;
let charset = imap::extensions::sort::SortCharset::Utf8;
let begin = page * page_size;
let end = begin + (page_size - 1);
let seqs: Vec<String> = self
.sess()?
.sort(&sort, charset, filter)
.context(format!(
"cannot search in {:?} with query {:?}",
mbox, filter
))?
.iter()
.map(|seq| seq.to_string())
.collect();
let seqs: Vec<String> = if sort.is_empty() {
self.sess()?
.search(query)
.context(format!(
"cannot find envelopes in {:?} with query {:?}",
mbox, query
))?
.iter()
.map(|seq| seq.to_string())
.collect()
} else {
let sort: SortCriteria = sort.try_into()?;
let charset = imap::extensions::sort::SortCharset::Utf8;
self.sess()?
.sort(&sort, charset, query)
.context(format!(
"cannot find envelopes in {:?} with query {:?}",
mbox, query
))?
.iter()
.map(|seq| seq.to_string())
.collect()
};
if seqs.is_empty() {
return Ok(Box::new(ImapEnvelopes::default()));
}

View file

@ -69,17 +69,12 @@ impl<'a> Backend<'a> for MaildirBackend<'a> {
fn get_envelopes(
&mut self,
mdir: &str,
_sort: &str,
filter: &str,
page_size: usize,
page: usize,
) -> Result<Box<dyn Envelopes>> {
let mdir = self.get_mdir_from_name(mdir)?;
let mail_entries = match filter {
"new" => mdir.list_new(),
_ => mdir.list_cur(),
};
let mut envelopes: MaildirEnvelopes = mail_entries
let mut envelopes: MaildirEnvelopes = mdir
.list_cur()
.try_into()
.context("cannot parse maildir envelopes from {:?}")?;
envelopes.sort_by(|a, b| b.date.partial_cmp(&a.date).unwrap());
@ -96,6 +91,19 @@ impl<'a> Backend<'a> for MaildirBackend<'a> {
Ok(Box::new(envelopes))
}
fn find_envelopes(
&mut self,
_mdir: &str,
_query: &str,
_sort: &str,
_page_size: usize,
_page: usize,
) -> Result<Box<dyn Envelopes>> {
Err(anyhow!(
"cannot find maildir envelopes: feature not implemented"
))
}
fn add_msg(&mut self, mdir: &str, msg: &[u8], flags: &str) -> Result<Box<dyn ToString>> {
let mdir = self.get_mdir_from_name(mdir)?;
let flags: MaildirFlags = flags.try_into()?;

View file

@ -51,18 +51,30 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
fn get_envelopes(
&mut self,
mdir: &str,
_sort: &str,
filter: &str,
page_size: usize,
page: usize,
) -> Result<Box<dyn Envelopes>> {
let query = self
unimplemented!();
}
fn find_envelopes(
&mut self,
_mdir: &str,
query: &str,
_sort: &str,
_page_size: usize,
_page: usize,
) -> Result<Box<dyn Envelopes>> {
let query_builder = self
.db
.create_query(filter)
.context("cannot create query")?;
let msgs: NotmuchEnvelopes = query
.create_query(query)
.context("cannot create notmuch query")?;
let msgs: NotmuchEnvelopes = query_builder
.search_messages()
.context("cannot get messages")?
.context(format!(
"cannot find notmuch envelopes with query {:?}",
query
))?
.try_into()?;
Ok(Box::new(msgs))
}

View file

@ -108,7 +108,7 @@ pub fn list<'a, P: PrinterService, B: Backend<'a> + ?Sized>(
) -> Result<()> {
let page_size = page_size.unwrap_or(config.default_page_size);
debug!("page size: {}", page_size);
let msgs = imap.get_envelopes(mbox, "arrival:desc", "all", page_size, page)?;
let msgs = imap.get_envelopes(mbox, page_size, page)?;
trace!("envelopes: {:?}", msgs);
printer.print_table(msgs, PrintTableOpts { max_width })
}
@ -273,7 +273,7 @@ pub fn search<'a, P: PrinterService, B: Backend<'a> + ?Sized>(
) -> Result<()> {
let page_size = page_size.unwrap_or(config.default_page_size);
debug!("page size: {}", page_size);
let msgs = backend.get_envelopes(mbox, "arrival:desc", &query, page_size, page)?;
let msgs = backend.find_envelopes(mbox, &query, "", page_size, page)?;
trace!("messages: {:#?}", msgs);
printer.print_table(msgs, PrintTableOpts { max_width })
}
@ -292,7 +292,7 @@ pub fn sort<'a, P: PrinterService, B: Backend<'a> + ?Sized>(
) -> Result<()> {
let page_size = page_size.unwrap_or(config.default_page_size);
debug!("page size: {}", page_size);
let msgs = backend.get_envelopes(mbox, &sort, &query, page_size, page)?;
let msgs = backend.find_envelopes(mbox, &query, &sort, page_size, page)?;
trace!("envelopes: {:#?}", msgs);
printer.print_table(msgs, PrintTableOpts { max_width })
}