use futures_lite::io::AsyncWrite;
use std::io::Error;
use std::pin::Pin;
use std::task::{Context, Poll};
use crate::base::write::{central_directory_size_field, ZipFileWriter};
use crate::error::{Zip64ErrorCase, ZipError};
use crate::spec::consts::NON_ZIP64_MAX_SIZE;
#[cfg(feature = "deflate64")]
use crate::{Compression, ZipEntryBuilder};
pub(crate) mod offset;
mod zip64;
pub(crate) struct AsyncSink;
impl AsyncWrite for AsyncSink {
fn poll_write(self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, Error>> {
Poll::Ready(Ok(buf.len()))
}
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Error>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Error>> {
Poll::Ready(Ok(()))
}
}
#[tokio::test]
async fn reject_large_archive_comment() {
let mut buffer = Vec::new();
let mut writer = ZipFileWriter::new(&mut buffer);
writer.comment("x".repeat(u16::MAX as usize + 1));
let result = writer.close().await;
assert!(matches!(result, Err(ZipError::CommentTooLarge)));
assert!(buffer.is_empty());
}
#[cfg(feature = "deflate64")]
#[tokio::test]
async fn reject_deflate64_whole_writes() {
let mut buffer = Vec::new();
let mut writer = ZipFileWriter::new(&mut buffer);
let entry = ZipEntryBuilder::new("file".into(), Compression::Deflate64);
let result = writer.write_entry_whole(entry, b"data").await;
assert!(matches!(result, Err(ZipError::FeatureNotSupported("Deflate64 writing"))));
assert!(buffer.is_empty());
}
#[cfg(feature = "deflate64")]
#[tokio::test]
async fn reject_deflate64_stream_writes() {
let mut buffer = Vec::new();
let mut writer = ZipFileWriter::new(&mut buffer);
let entry = ZipEntryBuilder::new("file".into(), Compression::Deflate64);
let result = writer.write_entry_stream(entry).await;
assert!(matches!(result, Err(ZipError::FeatureNotSupported("Deflate64 writing"))));
assert!(buffer.is_empty());
}
#[test]
fn large_central_directory_size_uses_zip64() {
let mut is_zip64 = false;
let field = central_directory_size_field(NON_ZIP64_MAX_SIZE as u64 + 1, false, &mut is_zip64).unwrap();
assert_eq!(field, NON_ZIP64_MAX_SIZE);
assert!(is_zip64);
}
#[test]
fn large_central_directory_size_errors_without_zip64() {
let mut is_zip64 = false;
let result = central_directory_size_field(NON_ZIP64_MAX_SIZE as u64 + 1, true, &mut is_zip64);
assert!(matches!(result, Err(ZipError::Zip64Needed(Zip64ErrorCase::LargeFile))));
assert!(!is_zip64);
}