diff --git a/rslib/src/import_export/package/apkg/import/notes.rs b/rslib/src/import_export/package/apkg/import/notes.rs index 805ea2feb..fbcf09b0a 100644 --- a/rslib/src/import_export/package/apkg/import/notes.rs +++ b/rslib/src/import_export/package/apkg/import/notes.rs @@ -187,7 +187,7 @@ impl<'n> NoteContext<'n> { fn import_notes(&mut self, notes: Vec, progress_fn: &mut ProgressFn) -> Result<()> { let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Notes(u))); - for mut note in notes.into_iter() { + for mut note in notes { progress.increment()?; if let Some(notetype_id) = self.remapped_notetypes.get(¬e.notetype_id) { if self.target_guids.contains_key(¬e.guid) { diff --git a/rslib/src/import_export/package/colpkg/import.rs b/rslib/src/import_export/package/colpkg/import.rs index c07e7a071..1b57340d8 100644 --- a/rslib/src/import_export/package/colpkg/import.rs +++ b/rslib/src/import_export/package/colpkg/import.rs @@ -48,7 +48,7 @@ pub fn import_colpkg( restore_media( &meta, - progress_fn, + &mut progress_fn, &mut archive, target_media_folder, media_db, @@ -88,17 +88,13 @@ fn restore_media( } std::fs::create_dir_all(media_folder)?; - let media_manager = MediaManager::new(media_folder, media_db)?; - let mut db_progress_fn = |u| progress_fn(ImportProgress::MediaCheck(u)).is_ok(); - media_manager.register_changes(&mut db_progress_fn, log)?; + let mut media_comparer = MediaComparer::new(meta, &mut progress_fn, &media_manager, log)?; - let mut get_checksum = media_manager.checksum_getter(); let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Media(u))); - - for entry in &media_entries { + for mut entry in media_entries { progress.increment()?; - maybe_restore_media_file(meta, media_folder, archive, entry, &mut get_checksum)?; + maybe_restore_media_file(meta, media_folder, archive, &mut entry, &mut media_comparer)?; } Ok(()) @@ -108,12 +104,16 @@ fn maybe_restore_media_file( meta: &Meta, media_folder: &Path, archive: &mut ZipArchive, - entry: &SafeMediaEntry, - get_checksum: &mut impl FnMut(&str) -> Result>, + entry: &mut SafeMediaEntry, + media_comparer: &mut MediaComparer, ) -> Result<()> { let file_path = entry.file_path(media_folder); let mut zip_file = entry.fetch_file(archive)?; - let already_exists = entry.is_equal_to(meta, &zip_file, &file_path, get_checksum)?; + if meta.media_list_is_hashmap() { + entry.size = zip_file.size() as u32; + } + + let already_exists = media_comparer.entry_is_equal_to(entry, &file_path)?; if !already_exists { restore_media_file(meta, &mut zip_file, &file_path)?; }; @@ -150,3 +150,31 @@ fn copy_collection( Ok(()) } + +#[allow(clippy::type_complexity)] +struct MediaComparer<'a>(Option Result> + 'a>>); + +impl<'a> MediaComparer<'a> { + fn new( + meta: &Meta, + mut progress_fn: impl FnMut(ImportProgress) -> Result<()>, + media_manager: &'a MediaManager, + log: &Logger, + ) -> Result { + Ok(Self(if meta.media_list_is_hashmap() { + None + } else { + let mut db_progress_fn = |u| progress_fn(ImportProgress::MediaCheck(u)).is_ok(); + media_manager.register_changes(&mut db_progress_fn, log)?; + Some(Box::new(media_manager.checksum_getter())) + })) + } + + fn entry_is_equal_to(&mut self, entry: &SafeMediaEntry, other_path: &Path) -> Result { + if let Some(ref mut get_checksum) = self.0 { + Ok(entry.has_checksum_equal_to(get_checksum)?) + } else { + Ok(entry.has_size_equal_to(other_path)) + } + } +} diff --git a/rslib/src/import_export/package/media.rs b/rslib/src/import_export/package/media.rs index 3fb370347..3613ffa72 100644 --- a/rslib/src/import_export/package/media.rs +++ b/rslib/src/import_export/package/media.rs @@ -25,7 +25,6 @@ use crate::{ /// Like [MediaEntry], but with a safe filename and set zip filename. pub(super) struct SafeMediaEntry { pub(super) name: String, - #[allow(dead_code)] pub(super) size: u32, pub(super) sha1: Sha1Hash, pub(super) index: usize, @@ -86,19 +85,15 @@ impl SafeMediaEntry { .map_err(|_| AnkiError::invalid_input(&format!("{} missing from archive", self.index))) } - pub(super) fn is_equal_to( + pub(super) fn has_checksum_equal_to( &self, - meta: &Meta, - self_zipped: &ZipFile, - other_path: &Path, get_checksum: &mut impl FnMut(&str) -> Result>, ) -> Result { - if meta.media_list_is_hashmap() { - Ok(fs::metadata(other_path) - .map_or(false, |metadata| metadata.len() == self_zipped.size())) - } else { - get_checksum(&self.name).map(|opt| opt.map_or(false, |sha1| sha1 == self.sha1)) - } + get_checksum(&self.name).map(|opt| opt.map_or(false, |sha1| sha1 == self.sha1)) + } + + pub(super) fn has_size_equal_to(&self, other_path: &Path) -> bool { + fs::metadata(other_path).map_or(false, |metadata| metadata.len() == self.size as u64) } pub(super) fn copy_from_archive(