summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2022-12-08 20:43:52 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2022-12-08 20:43:52 +0200
commit7382e30160a934ce97dd73c1be44640d5b4a4c75 (patch)
tree243f89426d5031bc9742c6a9a7152b98ca44a833
parent2427b097c5c40f3212a105cb40f913c9860ae2a8 (diff)
downloadmeli-7382e30160a934ce97dd73c1be44640d5b4a4c75.zip
Convert EnvelopeHash from typedef to wrapper struct
-rw-r--r--melib/src/backends/imap/cache.rs26
-rw-r--r--melib/src/backends/imap/protocol_parser.rs4
-rw-r--r--melib/src/backends/jmap/objects/email.rs9
-rw-r--r--melib/src/backends/maildir/backend.rs2
-rw-r--r--melib/src/backends/nntp/protocol_parser.rs2
-rw-r--r--melib/src/backends/notmuch.rs7
-rw-r--r--melib/src/backends/notmuch/message.rs6
-rw-r--r--melib/src/email.rs34
-rw-r--r--melib/src/email/compose.rs2
-rw-r--r--melib/src/sqlite3.rs16
-rw-r--r--src/sqlite3.rs20
11 files changed, 71 insertions, 57 deletions
diff --git a/melib/src/backends/imap/cache.rs b/melib/src/backends/imap/cache.rs
index 5ddb2b68..9ee95665 100644
--- a/melib/src/backends/imap/cache.rs
+++ b/melib/src/backends/imap/cache.rs
@@ -464,7 +464,7 @@ mod sqlite3_m {
max_uid = std::cmp::max(max_uid, *uid);
tx.execute(
"INSERT OR REPLACE INTO envelopes (hash, uid, mailbox_hash, modsequence, envelope) VALUES (?1, ?2, ?3, ?4, ?5)",
- sqlite3::params![envelope.hash() as i64, *uid as Sqlite3UID, mailbox_hash as i64, modseq, &envelope],
+ sqlite3::params![envelope.hash(), *uid as Sqlite3UID, mailbox_hash as i64, modseq, &envelope],
).chain_err_summary(|| format!("Could not insert envelope {} {} in header_cache of account {}", envelope.message_id(), envelope.hash(), uid_store.account_name))?;
}
}
@@ -586,16 +586,13 @@ mod sqlite3_m {
)?;
let x = stmt
- .query_map(
- sqlite3::params![mailbox_hash as i64, env_hash as i64],
- |row| {
- Ok((
- row.get(0).map(|u: Sqlite3UID| u as UID)?,
- row.get(1)?,
- row.get(2)?,
- ))
- },
- )?
+ .query_map(sqlite3::params![mailbox_hash as i64, env_hash], |row| {
+ Ok((
+ row.get(0).map(|u: Sqlite3UID| u as UID)?,
+ row.get(1)?,
+ row.get(2)?,
+ ))
+ })?
.collect::<std::result::Result<_, _>>()?;
x
}
@@ -635,10 +632,9 @@ mod sqlite3_m {
"SELECT rfc822 FROM envelopes WHERE mailbox_hash = ?1 AND hash = ?2;",
)?;
let x = stmt
- .query_map(
- sqlite3::params![mailbox_hash as i64, env_hash as i64],
- |row| row.get(0),
- )?
+ .query_map(sqlite3::params![mailbox_hash as i64, env_hash], |row| {
+ row.get(0)
+ })?
.collect::<std::result::Result<_, _>>()?;
x
}
diff --git a/melib/src/backends/imap/protocol_parser.rs b/melib/src/backends/imap/protocol_parser.rs
index bb828a3e..eaf2b08f 100644
--- a/melib/src/backends/imap/protocol_parser.rs
+++ b/melib/src/backends/imap/protocol_parser.rs
@@ -1336,7 +1336,7 @@ pub fn envelope(input: &[u8]) -> IResult<&[u8], Envelope> {
Ok((
input,
({
- let mut env = Envelope::new(0);
+ let mut env = Envelope::new(EnvelopeHash::default());
if let Some(date) = date {
env.set_date(&date);
if let Ok(d) =
@@ -1760,5 +1760,5 @@ pub fn generate_envelope_hash(mailbox_path: &str, uid: &UID) -> EnvelopeHash {
let mut h = DefaultHasher::new();
h.write_usize(*uid);
h.write(mailbox_path.as_bytes());
- h.finish()
+ EnvelopeHash(h.finish())
}
diff --git a/melib/src/backends/jmap/objects/email.rs b/melib/src/backends/jmap/objects/email.rs
index b1e2f3c4..2c83409f 100644
--- a/melib/src/backends/jmap/objects/email.rs
+++ b/melib/src/backends/jmap/objects/email.rs
@@ -26,9 +26,7 @@ use core::marker::PhantomData;
use serde::de::{Deserialize, Deserializer};
use serde_json::value::RawValue;
use serde_json::Value;
-use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
-use std::hash::Hasher;
mod import;
pub use import::*;
@@ -42,9 +40,7 @@ impl Object for ThreadObject {
impl Id<EmailObject> {
pub fn into_hash(&self) -> EnvelopeHash {
- let mut h = DefaultHasher::new();
- h.write(self.inner.as_bytes());
- h.finish()
+ EnvelopeHash::from_bytes(self.inner.as_bytes())
}
}
@@ -250,7 +246,7 @@ impl std::fmt::Display for EmailAddress {
impl std::convert::From<EmailObject> for crate::Envelope {
fn from(mut t: EmailObject) -> crate::Envelope {
- let mut env = crate::Envelope::new(0);
+ let mut env = crate::Envelope::new(t.id.into_hash());
if let Ok(d) = crate::email::parser::dates::rfc5322_date(env.date_as_str().as_bytes()) {
env.set_datetime(d);
}
@@ -327,7 +323,6 @@ impl std::convert::From<EmailObject> for crate::Envelope {
}
}
- env.set_hash(t.id.into_hash());
env
}
}
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index 55b6ca47..a8ac0a55 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -150,7 +150,7 @@ macro_rules! get_path_hash {
pub fn get_file_hash(file: &Path) -> EnvelopeHash {
let mut hasher = DefaultHasher::default();
file.hash(&mut hasher);
- hasher.finish()
+ EnvelopeHash(hasher.finish())
}
pub fn move_to_cur(p: PathBuf) -> Result<PathBuf> {
diff --git a/melib/src/backends/nntp/protocol_parser.rs b/melib/src/backends/nntp/protocol_parser.rs
index c9d78e47..2501288b 100644
--- a/melib/src/backends/nntp/protocol_parser.rs
+++ b/melib/src/backends/nntp/protocol_parser.rs
@@ -119,7 +119,7 @@ pub fn over_article(input: &str) -> IResult<&str, (UID, Envelope)> {
let mut hasher = DefaultHasher::new();
hasher.write(num.as_bytes());
hasher.write(message_id.unwrap_or_default().as_bytes());
- hasher.finish()
+ EnvelopeHash(hasher.finish())
};
let mut env = Envelope::new(env_hash);
if let Some(date) = date {
diff --git a/melib/src/backends/notmuch.rs b/melib/src/backends/notmuch.rs
index 81d98e62..5fc2331e 100644
--- a/melib/src/backends/notmuch.rs
+++ b/melib/src/backends/notmuch.rs
@@ -903,8 +903,11 @@ impl MailBackend for NotmuchDb {
s.push(' ');
s
} else {
- return Err(MeliError::new("Mailbox with hash {} not found!")
- .set_kind(crate::error::ErrorKind::Bug));
+ return Err(MeliError::new(format!(
+ "Mailbox with hash {} not found!",
+ mailbox_hash
+ ))
+ .set_kind(crate::error::ErrorKind::Bug));
}
} else {
String::new()
diff --git a/melib/src/backends/notmuch/message.rs b/melib/src/backends/notmuch/message.rs
index 16c5123c..a8104b4d 100644
--- a/melib/src/backends/notmuch/message.rs
+++ b/melib/src/backends/notmuch/message.rs
@@ -58,11 +58,7 @@ impl<'m> Message<'m> {
pub fn env_hash(&self) -> EnvelopeHash {
let msg_id = unsafe { call!(self.lib, notmuch_message_get_message_id)(self.message) };
let c_str = unsafe { CStr::from_ptr(msg_id) };
- {
- let mut hasher = DefaultHasher::default();
- c_str.hash(&mut hasher);
- hasher.finish()
- }
+ EnvelopeHash::from_bytes(c_str.to_bytes_with_nul())
}
pub fn header(&self, header: &CStr) -> Option<&[u8]> {
diff --git a/melib/src/email.rs b/melib/src/email.rs
index 538d8887..75db0231 100644
--- a/melib/src/email.rs
+++ b/melib/src/email.rs
@@ -198,7 +198,31 @@ impl Mail {
}
}
-pub type EnvelopeHash = u64;
+#[derive(
+ Hash, Eq, PartialEq, Debug, Ord, PartialOrd, Default, Serialize, Deserialize, Copy, Clone,
+)]
+#[repr(transparent)]
+pub struct EnvelopeHash(pub u64);
+
+impl EnvelopeHash {
+ #[inline(always)]
+ pub fn from_bytes(bytes: &[u8]) -> Self {
+ let mut h = DefaultHasher::new();
+ h.write(bytes);
+ Self(h.finish())
+ }
+
+ #[inline(always)]
+ pub const fn to_be_bytes(self) -> [u8; 8] {
+ self.0.to_be_bytes()
+ }
+}
+
+impl core::fmt::Display for EnvelopeHash {
+ fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
+ write!(fmt, "{}", self.0)
+ }
+}
/// `Envelope` represents all the header and structure data of an email we need to know.
///
@@ -244,7 +268,7 @@ impl core::fmt::Debug for Envelope {
impl Default for Envelope {
fn default() -> Self {
- Envelope::new(0)
+ Envelope::new(EnvelopeHash::default())
}
}
@@ -276,9 +300,7 @@ impl Envelope {
}
pub fn from_bytes(bytes: &[u8], flags: Option<Flag>) -> Result<Envelope> {
- let mut h = DefaultHasher::new();
- h.write(bytes);
- let mut e = Envelope::new(h.finish());
+ let mut e = Envelope::new(EnvelopeHash::from_bytes(bytes));
let res = e.populate_headers(bytes).ok();
if res.is_some() {
if let Some(f) = flags {
@@ -396,7 +418,7 @@ impl Envelope {
}
if self.message_id.raw().is_empty() {
let hash = self.hash;
- self.set_message_id(format!("<{:x}>", hash).as_bytes());
+ self.set_message_id(format!("<{:x}>", hash.0).as_bytes());
}
if self.references.is_some() {
if let Some(pos) = self
diff --git a/melib/src/email/compose.rs b/melib/src/email/compose.rs
index afecdb4e..1454ece3 100644
--- a/melib/src/email/compose.rs
+++ b/melib/src/email/compose.rs
@@ -90,7 +90,7 @@ impl FromStr for Draft {
ret.headers
.insert(k.try_into()?, String::from_utf8(v.to_vec())?);
}
- let body = Envelope::new(0).body_bytes(s.as_bytes());
+ let body = Envelope::new(EnvelopeHash::default()).body_bytes(s.as_bytes());
ret.body = String::from_utf8(body.decode(Default::default()))?;
diff --git a/melib/src/sqlite3.rs b/melib/src/sqlite3.rs
index 17a7b67f..898454f6 100644
--- a/melib/src/sqlite3.rs
+++ b/melib/src/sqlite3.rs
@@ -19,7 +19,7 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
-use crate::{error::*, logging::log, Envelope};
+use crate::{error::*, logging::log, Envelope, EnvelopeHash};
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput};
pub use rusqlite::{self, params, Connection};
use std::path::PathBuf;
@@ -159,3 +159,17 @@ impl FromSql for Envelope {
.map_err(|e| FromSqlError::Other(Box::new(e)))
}
}
+
+impl ToSql for EnvelopeHash {
+ fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
+ Ok(ToSqlOutput::from(self.0 as i64))
+ }
+}
+
+impl FromSql for EnvelopeHash {
+ fn column_result(value: rusqlite::types::ValueRef) -> FromSqlResult<Self> {
+ let b: i64 = FromSql::column_result(value)?;
+
+ Ok(EnvelopeHash(b as u64))
+ }
+}
diff --git a/src/sqlite3.rs b/src/sqlite3.rs
index c2ad9659..deecf295 100644
--- a/src/sqlite3.rs
+++ b/src/sqlite3.rs
@@ -30,17 +30,12 @@ use melib::{
backends::{MailBackend, ResultFuture},
email::{Envelope, EnvelopeHash},
log,
- sqlite3::{
- self as melib_sqlite3,
- rusqlite::{self, params},
- DatabaseDescription,
- },
+ sqlite3::{self as melib_sqlite3, rusqlite::params, DatabaseDescription},
thread::{SortField, SortOrder},
MeliError, Result, ERROR,
};
use smallvec::SmallVec;
-use std::convert::TryInto;
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
@@ -367,16 +362,9 @@ pub fn search(
.map_err(|e| MeliError::new(e.to_string()))?;
let results = stmt
- .query_map([], |row| row.get(0))
- .map_err(|e| MeliError::new(e.to_string()))?
- .map(|r: std::result::Result<Vec<u8>, rusqlite::Error>| {
- Ok(u64::from_be_bytes(
- r.map_err(|e| MeliError::new(e.to_string()))?
- .as_slice()
- .try_into()
- .map_err(|e: std::array::TryFromSliceError| MeliError::new(e.to_string()))?,
- ))
- })
+ .query_map([], |row| row.get::<_, EnvelopeHash>(0))
+ .map_err(MeliError::from)?
+ .map(|item| item.map_err(MeliError::from))
.collect::<Result<SmallVec<[EnvelopeHash; 512]>>>();
Ok(Box::pin(async { results }))
}