ZipFileBuilder

Struct ZipFileBuilder 

Source
pub struct ZipFileBuilder<'archive, 'name, W> { /* private fields */ }
Expand description

A builder for creating a new file entry in a ZIP archive.

Implementations§

Source§

impl<'archive, W> ZipFileBuilder<'archive, '_, W>
where W: Write,

Source

pub fn compression_method(self, compression_method: CompressionMethod) -> Self

Sets the compression method for the file entry.

Source

pub fn last_modified(self, modification_time: UtcDateTime) -> Self

Sets the modification time for the file entry.

Only accepts UTC timestamps to ensure Extended Timestamp fields are written correctly.

Source

pub fn unix_permissions(self, permissions: u32) -> Self

Sets the Unix permissions for the file entry.

Accepts either:

  • Basic permission bits (e.g., 0o644 for rw-r–r–, 0o755 for rwxr-xr-x)
  • Full Unix mode including file type (e.g., 0o100644 for regular file, 0o040755 for directory)
  • Special permission bits are preserved (SUID: 0o4000, SGID: 0o2000, sticky: 0o1000)

When set, the archive will be created with Unix-compatible “version made by” field to ensure proper interpretation of the permissions by zip readers.

Source

pub fn extra_field( self, id: ExtraFieldId, data: &[u8], location: Header, ) -> Result<Self, Error>

Adds an extra field to this file entry.

Extra fields contain additional metadata about files in ZIP archives, such as timestamps, alignment information, and platform-specific data.

No deduplication is performed - duplicate field IDs will result in multiple entries

Will return an error if the total size exceeds 65,535 bytes for the specified headers.

Rawzip will automatically add extra fields:

  • EXTENDED_TIMESTAMP when last_modified() is set
  • ZIP64 when 32-bit thresholds are met
§Examples

Create files with different extra field headers and verify the behavior. Only the central directory is checked. To check the local extra fields, see ZipEntry::local_header

let mut output = Cursor::new(Vec::new());
let mut archive = ZipArchiveWriter::new(&mut output);

let my_custom_field = ExtraFieldId::new(0x6666);

// File with extra fields only in the local file header
let mut local_file = archive.new_file("video.mp4")
    .extra_field(my_custom_field, b"field1", Header::LOCAL)?
    .create()?;
let mut writer = ZipDataWriter::new(&mut local_file);
writer.write_all(b"video data")?;
let (_, desc) = writer.finish()?;
local_file.finish(desc)?;

// File with extra fields only in the central directory
let mut central_file = archive.new_file("document.pdf")
    .extra_field(my_custom_field, b"field2", Header::CENTRAL)?
    .create()?;
let mut writer = ZipDataWriter::new(&mut central_file);
writer.write_all(b"PDF content")?;
let (_, desc) = writer.finish()?;
central_file.finish(desc)?;

// File with extra fields in both headers for maximum compatibility
assert_eq!(Header::default(), Header::LOCAL | Header::CENTRAL);
let mut both_file = archive.new_file("important.dat")
    .extra_field(my_custom_field, b"field3", Header::default())?
    .create()?;
let mut writer = ZipDataWriter::new(&mut both_file);
writer.write_all(b"important data")?;
let (_, desc) = writer.finish()?;
both_file.finish(desc)?;

archive.finish()?;

// Verify the behavior when reading back the central directory
let zip_data = output.into_inner();
let archive = ZipArchive::from_slice(&zip_data)?;

for entry_result in archive.entries() {
    let entry = entry_result?;
     
    // Find our custom field in the central directory
    let custom_field_data = entry.extra_fields()
        .find(|(id, _)| *id == my_custom_field)
        .map(|(_, data)| data);
     
    match entry.file_path().as_ref() {
        b"video.mp4" => {
            // local only field should not be in central directory
            assert_eq!(custom_field_data, None);
        }
        b"document.pdf" => {
            // central only field should be in central directory
            assert_eq!(custom_field_data, Some(b"field2".as_slice()));
        }
        b"important.dat" => {
            // both location field should be in central directory
            assert_eq!(custom_field_data, Some(b"field3".as_slice()));
        }
        _ => {}
    }
}
Source

pub fn crc32(self, crc32_option: Crc32Option) -> Self

Sets the CRC32 calculation option for the file entry.

By default, CRC32 is calculated automatically from the data. Use this method to:

  • Skip CRC32 calculation entirely (for performance or when verification isn’t desired)
  • Provide a pre-calculated CRC32 value
Source

pub fn create(self) -> Result<ZipEntryWriter<'archive, W>, Error>

👎Deprecated since 0.4.0: Use start() method instead as it allows for more flexibility (ie: CRC configuration)

Creates the file entry and returns a writer for the file’s content.

Source

pub fn start( self, ) -> Result<(ZipEntryWriter<'archive, W>, ZipDataWriterConfig), Error>

Mark the start of file data

Returns a tuple:

  • entry handles the ZIP format and writes compressed data to the archive
  • config constructs data writers that handle uncompressed data and CRC32 calculation
§Examples

For stored (uncompressed) files:

let (mut entry, config) = archive.new_file("file.txt").start().unwrap();
let mut writer = config.wrap(&mut entry);
writer.write_all(b"Hello").unwrap();
let (_, output) = writer.finish().unwrap();
entry.finish(output).unwrap();

For deflate compression:

let (mut entry, config) = archive.new_file("file.txt").start().unwrap();
let encoder = flate2::write::DeflateEncoder::new(&mut entry, flate2::Compression::default());
let mut writer = config.wrap(encoder);
writer.write_all(b"Hello").unwrap();
let (encoder, output) = writer.finish().unwrap();
encoder.finish().unwrap();
entry.finish(output).unwrap();

Trait Implementations§

Source§

impl<'archive, 'name, W: Debug> Debug for ZipFileBuilder<'archive, 'name, W>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'archive, 'name, W> Freeze for ZipFileBuilder<'archive, 'name, W>

§

impl<'archive, 'name, W> RefUnwindSafe for ZipFileBuilder<'archive, 'name, W>
where W: RefUnwindSafe,

§

impl<'archive, 'name, W> Send for ZipFileBuilder<'archive, 'name, W>
where W: Send,

§

impl<'archive, 'name, W> Sync for ZipFileBuilder<'archive, 'name, W>
where W: Sync,

§

impl<'archive, 'name, W> Unpin for ZipFileBuilder<'archive, 'name, W>

§

impl<'archive, 'name, W> !UnwindSafe for ZipFileBuilder<'archive, 'name, W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.