@@ -281,22 +281,29 @@ pub fn sync(
281
281
} )
282
282
. unwrap_or_else ( || full_sync ( & mut remote) ) ?;
283
283
284
+ // Get ids for any emails we think are in the maildir but are not
285
+ let missing_ids: HashSet < jmap:: Id > = local_emails. values ( ) . filter ( |e| !local. email_exists_on_disk ( e) ) . map ( |e| e. id . clone ( ) ) . collect ( ) ;
286
+
284
287
// Retrieve the updated `Email` objects from the server.
285
288
stdout. set_color ( & info_color_spec) . context ( LogSnafu { } ) ?;
286
289
write ! ( stdout, "Retrieving metadata..." ) . context ( LogSnafu { } ) ?;
287
290
stdout. reset ( ) . context ( LogSnafu { } ) ?;
288
- writeln ! ( stdout, " ({} possibly changed)" , updated_ids. len( ) ) . context ( LogSnafu { } ) ?;
291
+ write ! ( stdout, " ({} possibly changed)" , updated_ids. len( ) ) . context ( LogSnafu { } ) ?;
292
+ if !missing_ids. is_empty ( ) {
293
+ write ! ( stdout, " ({} lost)" , missing_ids. len( ) ) . context ( LogSnafu { } ) ?
294
+ }
295
+ writeln ! ( stdout, "" ) . context ( LogSnafu { } ) ?;
289
296
stdout. flush ( ) . context ( LogSnafu { } ) ?;
290
297
291
298
let remote_emails = remote
292
- . get_emails ( updated_ids. iter ( ) , & mailboxes, & config. tags )
299
+ . get_emails ( [ updated_ids, missing_ids . clone ( ) ] . iter ( ) . flatten ( ) , & mailboxes, & config. tags )
293
300
. context ( GetRemoteEmailsSnafu { } ) ?;
294
301
295
302
// Before merging, download the new files into the cache.
296
303
let mut new_emails: HashMap < jmap:: Id , NewEmail > = remote_emails
297
304
. values ( )
298
305
. filter ( |remote_email| match local_emails. get ( & remote_email. id ) {
299
- Some ( local_email) => local_email. blob_id != remote_email. blob_id ,
306
+ Some ( local_email) => local_email. blob_id != remote_email. blob_id || !local . email_exists_on_disk ( local_email ) ,
300
307
None => true ,
301
308
} )
302
309
. map ( |remote_email| {
@@ -310,10 +317,13 @@ pub fn sync(
310
317
)
311
318
} )
312
319
. collect ( ) ;
313
-
320
+
314
321
let new_emails_missing_from_cache: Vec < & NewEmail > = new_emails
315
322
. values ( )
316
- . filter ( |x| !x. cache_path . exists ( ) && !local_emails. contains_key ( & x. remote_email . id ) )
323
+ . filter ( |x| match local_emails. get ( & x. remote_email . id ) {
324
+ Some ( le) => !local. email_exists_on_disk ( le) ,
325
+ None => !x. cache_path . exists ( ) ,
326
+ } )
317
327
. collect ( ) ;
318
328
319
329
if !new_emails_missing_from_cache. is_empty ( ) {
@@ -442,8 +452,10 @@ pub fn sync(
442
452
. add_new_email ( & new_email)
443
453
. context ( AddLocalEmailSnafu { } ) ?;
444
454
if let Some ( e) = local_emails. get ( & new_email. remote_email . id ) {
445
- // Move the old message to the destroyed emails set.
446
- destroyed_local_emails. push ( e) ;
455
+ // It already existed; delete old versions, but not ones we're reloading
456
+ if !missing_ids. contains ( & e. id ) {
457
+ destroyed_local_emails. push ( e) ;
458
+ }
447
459
}
448
460
Ok ( ( local_email. id . clone ( ) , local_email) )
449
461
} )
0 commit comments