This commit is contained in:
Michael Zhang 2021-10-28 22:20:03 -05:00
parent aa4e336d32
commit 50bd0a83d4
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
3 changed files with 74 additions and 7 deletions

View file

@ -3,12 +3,23 @@ CREATE TABLE "accounts" (
); );
CREATE TABLE "mailboxes" ( CREATE TABLE "mailboxes" (
"account" INTEGER, "account" INTEGER NOT NULL,
"name" TEXT, "name" TEXT NOT NULL,
"uidvalidity" INTEGER NOT NULL,
PRIMARY KEY ("account", "name") PRIMARY KEY ("account", "name")
); );
CREATE TABLE "messages" ( CREATE TABLE "messages" (
"id" TEXT PRIMARY KEY "id" TEXT PRIMARY KEY,
"date" DATETIME,
"subject" TEXT,
"from" JSON,
"sender" JSON,
"reply_to" JSON,
"to" JSON,
"cc" JSON,
"bcc" JSON,
"in_reply_to" TEXT,
"message_id" TEXT,
); );

View file

@ -219,7 +219,7 @@ impl ClientAuthenticated {
/// Runs the SEARCH command /// Runs the SEARCH command
pub async fn uid_search(&mut self) -> Result<Vec<u32>> { pub async fn uid_search(&mut self) -> Result<Vec<u32>> {
let cmd = Command::UidSearch(CommandSearch { let cmd = Command::UidSearch(CommandSearch {
criteria: SearchCriteria::All, criteria: SearchCriteria::all(),
}); });
let stream = self.execute(cmd).await?; let stream = self.execute(cmd).await?;
let (_, data) = stream.wait().await?; let (_, data) = stream.wait().await?;

View file

@ -1,4 +1,4 @@
use std::io::{self, Write}; use std::{collections::HashSet, io::{self, Write}, ops::{Bound, RangeBounds}};
use format_bytes::DisplayBytes; use format_bytes::DisplayBytes;
use panorama_proto_common::{quote_string, Bytes}; use panorama_proto_common::{quote_string, Bytes};
@ -175,7 +175,63 @@ impl DisplayBytes for FetchItems {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum FetchAttr {} pub enum FetchAttr {}
// TODO: not the most efficient representation but I'll optimize if this ever actually becomes a
// problem
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum SearchCriteria { pub struct SearchCriteria(HashSet<(Bound<u32>, Bound<u32>)>);
All,
impl SearchCriteria {
pub fn all() -> Self {
let mut set = HashSet::new();
set.insert((Bound::Unbounded, Bound::Unbounded));
SearchCriteria(set)
}
pub fn contains(&self, n: u32) -> bool {
for range in self.0.iter() {
if range.contains(&n) {
return true;
}
}
false
}
}
impl DisplayBytes for SearchCriteria {
fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> {
// TODO: is it faster to batch these up or not?
for (i, range) in self.0.iter().enumerate() {
if i != 0 {
write_bytes!(w, b",")?;
}
match range.0 {
Bound::Excluded(n) => write_bytes!(w, b"{}", &(n + 1))?,
Bound::Included(n) => write_bytes!(w, b"{}", &n)?,
Bound::Unbounded => write_bytes!(w, b"*")?,
}
write_bytes!(w, b":")?;
match range.1 {
Bound::Excluded(n) => write_bytes!(w, b"{}", &(n - 1))?,
Bound::Included(n) => write_bytes!(w, b"{}", &n)?,
Bound::Unbounded => write_bytes!(w, b"*")?,
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_search_criteria() {
// TODO: is there a trivial case?
assert_eq!(format_bytes!(b"{}", SearchCriteria::all()), b"*:*");
}
} }