melib: change BackendOp::set_flag() signature
parent
ede512200b
commit
7463248da8
|
@ -250,7 +250,7 @@ pub trait BackendOp: ::std::fmt::Debug + ::std::marker::Send {
|
|||
fn fetch_headers(&mut self) -> Result<&[u8]>;
|
||||
fn fetch_body(&mut self) -> Result<&[u8]>;
|
||||
fn fetch_flags(&self) -> Flag;
|
||||
fn set_flag(&mut self, envelope: &mut Envelope, flag: Flag) -> Result<()>;
|
||||
fn set_flag(&mut self, envelope: &mut Envelope, flag: Flag, value: bool) -> Result<()>;
|
||||
}
|
||||
|
||||
/// Wrapper for BackendOps that are to be set read-only.
|
||||
|
@ -284,7 +284,7 @@ impl BackendOp for ReadOnlyOp {
|
|||
fn fetch_flags(&self) -> Flag {
|
||||
self.op.fetch_flags()
|
||||
}
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, _flag: Flag) -> Result<()> {
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, _flag: Flag, _value: bool) -> Result<()> {
|
||||
Err(MeliError::new("read-only set."))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,6 +230,9 @@ impl BackendOp for ImapOp {
|
|||
} else {
|
||||
let mut response = String::with_capacity(8 * 1024);
|
||||
let mut conn = self.connection.lock().unwrap();
|
||||
conn.send_command(format!("EXAMINE \"{}\"", &self.folder_path,).as_bytes())
|
||||
.unwrap();
|
||||
conn.read_response(&mut response).unwrap();
|
||||
conn.send_command(format!("UID FETCH {} FLAGS", self.uid).as_bytes())
|
||||
.unwrap();
|
||||
conn.read_response(&mut response).unwrap();
|
||||
|
@ -238,7 +241,7 @@ impl BackendOp for ImapOp {
|
|||
response.len(),
|
||||
response.lines().collect::<Vec<&str>>().len()
|
||||
);
|
||||
match protocol_parser::uid_fetch_response(response.as_bytes())
|
||||
match protocol_parser::uid_fetch_flags_response(response.as_bytes())
|
||||
.to_full_result()
|
||||
.map_err(MeliError::from)
|
||||
{
|
||||
|
@ -248,12 +251,10 @@ impl BackendOp for ImapOp {
|
|||
/* TODO: Trigger cache invalidation here. */
|
||||
panic!(format!("message with UID {} was not found", self.uid));
|
||||
}
|
||||
let (uid, flags, _) = v[0];
|
||||
let (uid, flags) = v[0];
|
||||
assert_eq!(uid, self.uid);
|
||||
if flags.is_some() {
|
||||
cache.flags = flags;
|
||||
self.flags.set(flags);
|
||||
}
|
||||
cache.flags = Some(flags);
|
||||
self.flags.set(Some(flags));
|
||||
}
|
||||
Err(e) => Err(e).unwrap(),
|
||||
}
|
||||
|
@ -261,7 +262,10 @@ impl BackendOp for ImapOp {
|
|||
self.flags.get().unwrap()
|
||||
}
|
||||
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, flag: Flag) -> Result<()> {
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, f: Flag, value: bool) -> Result<()> {
|
||||
let mut flags = self.fetch_flags();
|
||||
flags.set(f, value);
|
||||
|
||||
let mut response = String::with_capacity(8 * 1024);
|
||||
let mut conn = self.connection.lock().unwrap();
|
||||
conn.send_command(format!("SELECT \"{}\"", &self.folder_path,).as_bytes())?;
|
||||
|
@ -271,33 +275,29 @@ impl BackendOp for ImapOp {
|
|||
format!(
|
||||
"UID STORE {} FLAGS.SILENT ({})",
|
||||
self.uid,
|
||||
flags_to_imap_list!(flag)
|
||||
flags_to_imap_list!(flags)
|
||||
)
|
||||
.as_bytes(),
|
||||
)?;
|
||||
conn.read_response(&mut response)?;
|
||||
debug!(&response);
|
||||
match protocol_parser::uid_fetch_response(response.as_bytes())
|
||||
match protocol_parser::uid_fetch_flags_response(response.as_bytes())
|
||||
.to_full_result()
|
||||
.map_err(MeliError::from)
|
||||
{
|
||||
Ok(v) => {
|
||||
if v.len() == 1 {
|
||||
debug!("responses len is {}", v.len());
|
||||
let (uid, flags, _) = v[0];
|
||||
let (uid, flags) = v[0];
|
||||
assert_eq!(uid, self.uid);
|
||||
if flags.is_some() {
|
||||
self.flags.set(flags);
|
||||
}
|
||||
self.flags.set(Some(flags));
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e).unwrap(),
|
||||
}
|
||||
conn.send_command(format!("EXAMINE \"{}\"", &self.folder_path,).as_bytes())?;
|
||||
conn.read_response(&mut response)?;
|
||||
let mut bytes_cache = self.uid_store.byte_cache.lock()?;
|
||||
let cache = bytes_cache.entry(self.uid).or_default();
|
||||
cache.flags = Some(flag);
|
||||
cache.flags = Some(flags);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ named!(
|
|||
named!(
|
||||
my_flags<Flag>,
|
||||
do_parse!(
|
||||
flags: separated_nonempty_list!(tag!(" "), preceded!(tag!("\\"), is_not!(")")))
|
||||
flags: separated_list!(tag!(" "), preceded!(tag!("\\"), is_not!(")")))
|
||||
>> ({
|
||||
let mut ret = Flag::default();
|
||||
for f in flags {
|
||||
|
@ -122,6 +122,20 @@ named!(
|
|||
)
|
||||
);
|
||||
|
||||
named!(
|
||||
pub uid_fetch_flags_response<Vec<(usize, Flag)>>,
|
||||
many0!(
|
||||
do_parse!(
|
||||
tag!("* ")
|
||||
>> take_while!(call!(is_digit))
|
||||
>> tag!(" FETCH (")
|
||||
>> uid_flags: permutation!(preceded!(ws!(tag!("UID ")), map_res!(digit, |s| { usize::from_str(unsafe { std::str::from_utf8_unchecked(s) }) })), preceded!(ws!(tag!("FLAGS ")), delimited!(tag!("("), byte_flags, tag!(")"))))
|
||||
>> tag!(")\r\n")
|
||||
>> ((uid_flags.0, uid_flags.1))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! flags_to_imap_list {
|
||||
($flags:ident) => {{
|
||||
let mut ret = String::new();
|
||||
|
|
|
@ -132,7 +132,7 @@ impl<'a> BackendOp for MaildirOp {
|
|||
flag
|
||||
}
|
||||
|
||||
fn set_flag(&mut self, envelope: &mut Envelope, f: Flag) -> Result<()> {
|
||||
fn set_flag(&mut self, envelope: &mut Envelope, f: Flag, value: bool) -> Result<()> {
|
||||
let path = self.path();
|
||||
let path = path.to_str().unwrap(); // Assume UTF-8 validity
|
||||
let idx: usize = path
|
||||
|
@ -141,7 +141,8 @@ impl<'a> BackendOp for MaildirOp {
|
|||
+ 3;
|
||||
let mut new_name: String = path[..idx].to_string();
|
||||
let mut flags = self.fetch_flags();
|
||||
flags.toggle(f);
|
||||
flags.set(f, value);
|
||||
|
||||
if !(flags & Flag::DRAFT).is_empty() {
|
||||
new_name.push('D');
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ impl BackendOp for MboxOp {
|
|||
flags
|
||||
}
|
||||
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, _flag: Flag) -> Result<()> {
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, _flag: Flag, _value: bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,21 +159,12 @@ impl Collection {
|
|||
&mut self,
|
||||
mut new_envelopes: FnvHashMap<EnvelopeHash, Envelope>,
|
||||
folder_hash: FolderHash,
|
||||
mailbox: &mut Mailbox,
|
||||
sent_folder: Option<FolderHash>,
|
||||
) -> Option<StackVec<FolderHash>> {
|
||||
self.sent_folder = sent_folder;
|
||||
new_envelopes.retain(|&h, e| {
|
||||
if self.message_ids.contains_key(e.message_id().raw()) {
|
||||
/* skip duplicates until a better way to handle them is found. */
|
||||
//FIXME
|
||||
mailbox.remove(h);
|
||||
false
|
||||
} else {
|
||||
self.message_ids.insert(e.message_id().raw().to_vec(), h);
|
||||
true
|
||||
}
|
||||
});
|
||||
for (h, e) in new_envelopes.iter() {
|
||||
self.message_ids.insert(e.message_id().raw().to_vec(), *h);
|
||||
}
|
||||
|
||||
let &mut Collection {
|
||||
ref mut threads,
|
||||
|
|
|
@ -556,10 +556,14 @@ impl Envelope {
|
|||
pub fn set_datetime(&mut self, new_val: chrono::DateTime<chrono::FixedOffset>) {
|
||||
self.timestamp = new_val.timestamp() as UnixTimestamp;
|
||||
}
|
||||
pub fn set_flag(&mut self, f: Flag, mut operation: Box<dyn BackendOp>) -> Result<()> {
|
||||
self.flags.toggle(f);
|
||||
operation.set_flag(self, f)?;
|
||||
Ok(())
|
||||
pub fn set_flag(
|
||||
&mut self,
|
||||
f: Flag,
|
||||
value: bool,
|
||||
mut operation: Box<dyn BackendOp>,
|
||||
) -> Result<()> {
|
||||
self.flags.set(f, value);
|
||||
operation.set_flag(self, f, value)
|
||||
}
|
||||
pub fn set_flags(&mut self, f: Flag) {
|
||||
self.flags = f;
|
||||
|
@ -569,14 +573,14 @@ impl Envelope {
|
|||
}
|
||||
pub fn set_seen(&mut self, operation: Box<dyn BackendOp>) -> Result<()> {
|
||||
if !self.flags.contains(Flag::SEEN) {
|
||||
self.set_flag(Flag::SEEN, operation)
|
||||
self.set_flag(Flag::SEEN, true, operation)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub fn set_unseen(&mut self, operation: Box<dyn BackendOp>) -> Result<()> {
|
||||
if self.flags.contains(Flag::SEEN) {
|
||||
self.set_flag(Flag::SEEN, operation)
|
||||
self.set_flag(Flag::SEEN, false, operation)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -595,6 +599,7 @@ impl Ord for Envelope {
|
|||
self.datetime().cmp(&other.datetime())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Envelope {
|
||||
fn partial_cmp(&self, other: &Envelope) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
|
|
|
@ -1292,7 +1292,10 @@ impl Component for MailView {
|
|||
let mut our_map = FnvHashMap::with_capacity_and_hasher(4, Default::default());
|
||||
our_map.insert("add_addresses_to_contacts", Key::Char('c'));
|
||||
our_map.insert("view_raw_source", Key::Alt('r'));
|
||||
if self.mode.is_attachment() || self.mode == ViewMode::Subview || self.mode == ViewMode::Raw
|
||||
if self.mode.is_attachment()
|
||||
|| self.mode == ViewMode::Subview
|
||||
|| self.mode == ViewMode::Raw
|
||||
|| self.mode == ViewMode::Url
|
||||
{
|
||||
our_map.insert("return_to_normal_view", Key::Char('r'));
|
||||
}
|
||||
|
|
|
@ -738,7 +738,7 @@ impl Account {
|
|||
m.merge(&envelopes);
|
||||
if let Some(updated_folders) =
|
||||
self.collection
|
||||
.merge(envelopes, folder_hash, m, self.sent_folder)
|
||||
.merge(envelopes, folder_hash, self.sent_folder)
|
||||
{
|
||||
for f in updated_folders {
|
||||
self.notify_fn.notify(f);
|
||||
|
|
Loading…
Reference in New Issue