@@ -1258,11 +1258,7 @@ impl<W: Write + Seek> ZipWriter<W> {
12581258 /// Ok(())
12591259 /// }
12601260 /// ```
1261- pub fn raw_copy_file_rename < S : ToString > (
1262- & mut self ,
1263- mut file : ZipFile ,
1264- name : S ,
1265- ) -> ZipResult < ( ) > {
1261+ pub fn raw_copy_file_rename < S : ToString > ( & mut self , file : ZipFile , name : S ) -> ZipResult < ( ) > {
12661262 let mut options = SimpleFileOptions :: default ( )
12671263 . large_file ( file. compressed_size ( ) . max ( file. size ( ) ) > spec:: ZIP64_BYTES_THR )
12681264 . last_modified_time (
@@ -1274,7 +1270,15 @@ impl<W: Write + Seek> ZipWriter<W> {
12741270 options = options. unix_permissions ( perms) ;
12751271 }
12761272 Self :: normalize_options ( & mut options) ;
1273+ self . raw_copy_file_rename_internal ( file, name, options)
1274+ }
12771275
1276+ fn raw_copy_file_rename_internal < S : ToString > (
1277+ & mut self ,
1278+ mut file : ZipFile ,
1279+ name : S ,
1280+ options : SimpleFileOptions ,
1281+ ) -> ZipResult < ( ) > {
12781282 let raw_values = ZipRawValues {
12791283 crc32 : file. crc32 ( ) ,
12801284 compressed_size : file. compressed_size ( ) ,
@@ -1330,6 +1334,47 @@ impl<W: Write + Seek> ZipWriter<W> {
13301334 self . raw_copy_file_rename ( file, name)
13311335 }
13321336
1337+ /// Add a new file using the already compressed data from a ZIP file being read and set the last
1338+ /// modified date and unix mode. This allows faster copies of the `ZipFile` since there is no need
1339+ /// to decompress and compress it again. Any `ZipFile` metadata other than the last modified date
1340+ /// and the unix mode is copied and not checked, for example the file CRC.
1341+ ///
1342+ /// ```no_run
1343+ /// use std::io::{Read, Seek, Write};
1344+ /// use zip::{DateTime, ZipArchive, ZipWriter};
1345+ ///
1346+ /// fn copy<R, W>(src: &mut ZipArchive<R>, dst: &mut ZipWriter<W>) -> zip::result::ZipResult<()>
1347+ /// where
1348+ /// R: Read + Seek,
1349+ /// W: Write + Seek,
1350+ /// {
1351+ /// // Retrieve file entry by name
1352+ /// let file = src.by_name("src_file.txt")?;
1353+ ///
1354+ /// // Copy the previously obtained file entry to the destination zip archive
1355+ /// dst.raw_copy_file_touch(file, DateTime::default(), Some(0o644))?;
1356+ ///
1357+ /// Ok(())
1358+ /// }
1359+ /// ```
1360+ pub fn raw_copy_file_touch (
1361+ & mut self ,
1362+ file : ZipFile ,
1363+ last_modified_time : DateTime ,
1364+ unix_mode : Option < u32 > ,
1365+ ) -> ZipResult < ( ) > {
1366+ let name = file. name ( ) . to_owned ( ) ;
1367+ let mut options = SimpleFileOptions :: default ( )
1368+ . large_file ( file. compressed_size ( ) . max ( file. size ( ) ) > spec:: ZIP64_BYTES_THR )
1369+ . last_modified_time ( last_modified_time)
1370+ . compression_method ( file. compression ( ) ) ;
1371+ if let Some ( perms) = unix_mode {
1372+ options = options. unix_permissions ( perms) ;
1373+ }
1374+ Self :: normalize_options ( & mut options) ;
1375+ self . raw_copy_file_rename_internal ( file, name, options)
1376+ }
1377+
13331378 /// Add a directory entry.
13341379 ///
13351380 /// As directories have no content, you must not call [`ZipWriter::write`] before adding a new file.
0 commit comments