Convert EnvelopeHash from typedef to wrapper struct
parent
2427b097c5
commit
7382e30160
|
@ -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| {
|
||||
.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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -903,7 +903,10 @@ impl MailBackend for NotmuchDb {
|
|||
s.push(' ');
|
||||
s
|
||||
} else {
|
||||
return Err(MeliError::new("Mailbox with hash {} not found!")
|
||||
return Err(MeliError::new(format!(
|
||||
"Mailbox with hash {} not found!",
|
||||
mailbox_hash
|
||||
))
|
||||
.set_kind(crate::error::ErrorKind::Bug));
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -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]> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()))?;
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue