zip_extensions/
preserve_symlinks_handler.rs1use crate::default_entry_handler::DefaultEntryHandler;
2use crate::entry_handler::EntryHandler;
3use crate::file_utils::make_relative_path;
4use std::io;
5use std::io::Write;
6use std::path::PathBuf;
7use zip::result::ZipResult;
8use zip::write::{FileOptionExtension, FileOptions};
9use zip::ZipWriter;
10
11pub struct PreserveSymlinksHandler;
12
13impl<T: FileOptionExtension> EntryHandler<T> for PreserveSymlinksHandler {
14 fn handle_entry<W: Write + io::Seek>(
15 &self,
16 writer: &mut ZipWriter<W>,
17 root: &PathBuf,
18 entry_path: &PathBuf,
19 file_options: FileOptions<T>,
20 buffer: &mut Vec<u8>,
21 ) -> ZipResult<()> {
22 let symlink_metadata = std::fs::symlink_metadata(entry_path)?;
23 let relative = make_relative_path(root, entry_path);
24
25 if symlink_metadata.is_symlink() {
26 let target = std::fs::read_link(entry_path)?;
27 writer.add_symlink(
28 relative.to_str().unwrap(),
29 target.to_str().unwrap(),
30 file_options,
31 )?;
32 return Ok(());
33 }
34
35 DefaultEntryHandler.handle_entry(writer, root, entry_path, file_options, buffer)
37 }
38}