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