@@ -281,22 +281,40 @@ 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
286
+ . values ( )
287
+ . filter ( |e| !local. email_exists_on_disk ( e) )
288
+ . map ( |e| e. id . clone ( ) )
289
+ . collect ( ) ;
290
+
284
291
// Retrieve the updated `Email` objects from the server.
285
292
stdout. set_color ( & info_color_spec) . context ( LogSnafu { } ) ?;
286
293
write ! ( stdout, "Retrieving metadata..." ) . context ( LogSnafu { } ) ?;
287
294
stdout. reset ( ) . context ( LogSnafu { } ) ?;
288
- writeln ! ( stdout, " ({} possibly changed)" , updated_ids. len( ) ) . context ( LogSnafu { } ) ?;
295
+ write ! ( stdout, " ({} possibly changed)" , updated_ids. len( ) ) . context ( LogSnafu { } ) ?;
296
+ if !missing_ids. is_empty ( ) {
297
+ write ! ( stdout, " ({} lost)" , missing_ids. len( ) ) . context ( LogSnafu { } ) ?
298
+ }
299
+ writeln ! ( stdout, "" ) . context ( LogSnafu { } ) ?;
289
300
stdout. flush ( ) . context ( LogSnafu { } ) ?;
290
301
291
302
let remote_emails = remote
292
- . get_emails ( updated_ids. iter ( ) , & mailboxes, & config. tags )
303
+ . get_emails (
304
+ [ updated_ids, missing_ids. clone ( ) ] . iter ( ) . flatten ( ) ,
305
+ & mailboxes,
306
+ & config. tags ,
307
+ )
293
308
. context ( GetRemoteEmailsSnafu { } ) ?;
294
309
295
310
// Before merging, download the new files into the cache.
296
311
let mut new_emails: HashMap < jmap:: Id , NewEmail > = remote_emails
297
312
. values ( )
298
313
. filter ( |remote_email| match local_emails. get ( & remote_email. id ) {
299
- Some ( local_email) => local_email. blob_id != remote_email. blob_id ,
314
+ Some ( local_email) => {
315
+ local_email. blob_id != remote_email. blob_id
316
+ || !local. email_exists_on_disk ( local_email)
317
+ }
300
318
None => true ,
301
319
} )
302
320
. map ( |remote_email| {
@@ -313,7 +331,10 @@ pub fn sync(
313
331
314
332
let new_emails_missing_from_cache: Vec < & NewEmail > = new_emails
315
333
. values ( )
316
- . filter ( |x| !x. cache_path . exists ( ) && !local_emails. contains_key ( & x. remote_email . id ) )
334
+ . filter ( |x| match local_emails. get ( & x. remote_email . id ) {
335
+ Some ( le) => !local. email_exists_on_disk ( le) ,
336
+ None => !x. cache_path . exists ( ) ,
337
+ } )
317
338
. collect ( ) ;
318
339
319
340
if !new_emails_missing_from_cache. is_empty ( ) {
@@ -442,8 +463,10 @@ pub fn sync(
442
463
. add_new_email ( & new_email)
443
464
. context ( AddLocalEmailSnafu { } ) ?;
444
465
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) ;
466
+ // It already existed; delete old versions, but not ones we're reloading
467
+ if !missing_ids. contains ( & e. id ) {
468
+ destroyed_local_emails. push ( e) ;
469
+ }
447
470
}
448
471
Ok ( ( local_email. id . clone ( ) , local_email) )
449
472
} )
0 commit comments