From 6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1 Mon Sep 17 00:00:00 2001 From: Igor Tolmachev Date: Sat, 29 Jun 2024 22:53:47 +0900 Subject: Add `Clone` derive and edit trait types --- src/zip/driver.rs | 75 ++++++++++++++++++++++++-------------------------- src/zip/error.rs | 2 ++ src/zip/file_driver.rs | 3 +- src/zip/file_info.rs | 6 ++-- 4 files changed, 42 insertions(+), 44 deletions(-) (limited to 'src/zip') diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 0db845d..a280dc7 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs @@ -2,13 +2,12 @@ use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; use crate::zip::{BitFlag, CompressionMethod, ZipError, ZipFile, ZipFileInfo, ZipResult}; use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; -use std::collections::HashMap as Map; use std::io::{Read, Seek, SeekFrom, Write}; pub struct Zip { io: Io, - files: Map, + files: Vec, comment: String, } @@ -80,7 +79,7 @@ impl ArchiveRead for Zip { }; // Read cd records - let mut files = Map::with_capacity(cd_records as usize); + let mut files = Vec::with_capacity(cd_records as usize); io.seek(SeekFrom::Start(cd_pointer))?; let buf = { let mut buf = vec![0; cd_size as usize]; @@ -135,52 +134,50 @@ impl ArchiveRead for Zip { } } - files.insert( - name.clone(), - ZipFileInfo::new( - CompressionMethod::from_struct_id(cdr.compression_method)?, - BitFlag::new(cdr.bit_flag), - NaiveDateTime::new( - NaiveDate::from_ymd_opt( - (cdr.dos_date as i32 >> 9 & 0x7F) + 1980, - cdr.dos_date as u32 >> 5 & 0xF, - cdr.dos_date as u32 & 0x1F, - ) - .ok_or(ZipError::InvalidDate)?, - NaiveTime::from_hms_opt( - (cdr.dos_time as u32 >> 11) & 0x1F, - (cdr.dos_time as u32 >> 5) & 0x3F, - (cdr.dos_time as u32 & 0x1F) * 2, - ) - .ok_or(ZipError::InvalidTime)?, + files.push(ZipFileInfo::new( + CompressionMethod::from_struct_id(cdr.compression_method)?, + BitFlag::new(cdr.bit_flag), + NaiveDateTime::new( + NaiveDate::from_ymd_opt( + (cdr.dos_date as i32 >> 9 & 0x7F) + 1980, + cdr.dos_date as u32 >> 5 & 0xF, + cdr.dos_date as u32 & 0x1F, ) - .and_local_timezone(Local) - .unwrap(), - cdr.crc, - compressed_size, - size, - header_pointer, - name, - comment, - ), - ); + .ok_or(ZipError::InvalidDate)?, + NaiveTime::from_hms_opt( + (cdr.dos_time as u32 >> 11) & 0x1F, + (cdr.dos_time as u32 >> 5) & 0x3F, + (cdr.dos_time as u32 & 0x1F) * 2, + ) + .ok_or(ZipError::InvalidTime)?, + ) + .and_local_timezone(Local) + .unwrap(), + cdr.crc, + compressed_size, + size, + header_pointer, + name, + comment, + )); } Ok(Self { io, files, comment }) } - fn files(&self) -> Vec<&Self::FileInfo> { - let mut files: Vec<&Self::FileInfo> = self.files.values().collect(); - files.sort_by_key(|f| &f.name); - files + fn files(&self) -> &Vec { + &self.files } - fn get_file_info(&self, name: &str) -> Option<&Self::FileInfo> { - self.files.get(name) + fn get_file_info(&self, index: usize) -> ZipResult<&Self::FileInfo> { + self.files.get(index).ok_or(ZipError::FileNotFound.into()) } - fn get_file_reader<'d>(&'d mut self, name: &str) -> Option> { - Some(ZipFile::new(&mut self.io, self.files.get(name)?).unwrap()) + fn get_file_reader<'d>(&'d mut self, index: usize) -> ZipResult> { + Ok(ZipFile::new( + &mut self.io, + self.files.get(index).ok_or(ZipError::FileNotFound)?, + )?) } } diff --git a/src/zip/error.rs b/src/zip/error.rs index d82de78..3acbf8c 100644 --- a/src/zip/error.rs +++ b/src/zip/error.rs @@ -20,6 +20,7 @@ pub enum ZipError { InvalidFileComment, NegativeFileOffset, + FileNotFound, } impl From for ArchiveError { @@ -57,6 +58,7 @@ impl Display for ZipError { Self::InvalidFileComment => write!(f, "Invalid file comment"), Self::NegativeFileOffset => write!(f, "Negative file offset"), + Self::FileNotFound => write!(f, "File not found"), } } } diff --git a/src/zip/file_driver.rs b/src/zip/file_driver.rs index 47b4242..51075e4 100644 --- a/src/zip/file_driver.rs +++ b/src/zip/file_driver.rs @@ -1,8 +1,7 @@ use crate::driver::FileDriver; use crate::zip::{ZipError, ZipFileInfo, ZipResult}; use std::io::{ - Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, Take, - Write, + Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write, }; pub struct ZipFile<'d, Io> { diff --git a/src/zip/file_info.rs b/src/zip/file_info.rs index 88322be..92d52f7 100644 --- a/src/zip/file_info.rs +++ b/src/zip/file_info.rs @@ -2,7 +2,7 @@ use crate::driver::ArchiveFileInfo; use crate::zip::{ZipError, ZipResult}; use chrono::{DateTime, Local}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum CompressionMethod { Store, Deflate, @@ -29,7 +29,7 @@ impl CompressionMethod { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct BitFlag { flag: u16, } @@ -121,7 +121,7 @@ impl BitFlag { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ZipFileInfo { pub compression_method: CompressionMethod, pub bit_flag: BitFlag, -- cgit v1.2.3