diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-06-27 00:22:52 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-06-27 00:22:52 +0900 |
| commit | a867677218c1d55dadfcac1ca5b8cd32a78a3c28 (patch) | |
| tree | 563133b148e29a0521401103a53f1ba0912765d2 | |
| parent | 18b613fc0b63cb6e5a9b408ef7f47da8f153d6c6 (diff) | |
| download | archivator-a867677218c1d55dadfcac1ca5b8cd32a78a3c28.tar.gz archivator-a867677218c1d55dadfcac1ca5b8cd32a78a3c28.zip | |
Implement file getter in archive
| -rw-r--r-- | src/archive.rs | 21 | ||||
| -rw-r--r-- | src/driver/driver.rs | 6 | ||||
| -rw-r--r-- | src/zip/archive.rs | 10 | ||||
| -rw-r--r-- | src/zip/driver.rs | 21 | ||||
| -rw-r--r-- | src/zip/file.rs | 2 | ||||
| -rw-r--r-- | src/zip/mod.rs | 3 | ||||
| -rw-r--r-- | tests/files/zip.zip | bin | 0 -> 427 bytes | |||
| -rw-r--r-- | tests/zip.rs | 16 |
8 files changed, 71 insertions, 8 deletions
diff --git a/src/archive.rs b/src/archive.rs index fe03a12..e635007 100644 --- a/src/archive.rs +++ b/src/archive.rs | |||
| @@ -1,20 +1,37 @@ | |||
| 1 | use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; | 1 | use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; |
| 2 | use crate::ArchiveResult; | 2 | use crate::ArchiveResult; |
| 3 | use std::fs::File; | ||
| 3 | use std::io::{Read, Write}; | 4 | use std::io::{Read, Write}; |
| 5 | use std::path::Path; | ||
| 4 | 6 | ||
| 5 | pub struct Archive<D: Driver> { | 7 | pub struct Archive<D: Driver> { |
| 6 | pub driver: D, | 8 | pub(crate) driver: D, |
| 7 | } | 9 | } |
| 8 | 10 | ||
| 9 | impl<D: ArchiveRead> Archive<D> | 11 | impl<D: ArchiveRead> Archive<D> |
| 10 | where | 12 | where |
| 11 | D::IO: std::io::Read, | 13 | D::IO: std::io::Read, |
| 12 | { | 14 | { |
| 13 | pub fn new(io: D::IO) -> ArchiveResult<Self, D::Error> { | 15 | pub fn read(io: D::IO) -> ArchiveResult<Self, D::Error> { |
| 14 | Ok(Self { | 16 | Ok(Self { |
| 15 | driver: D::read(io)?, | 17 | driver: D::read(io)?, |
| 16 | }) | 18 | }) |
| 17 | } | 19 | } |
| 20 | |||
| 21 | pub fn read_from_file(path: impl AsRef<Path>) -> ArchiveResult<Self, D::Error> | ||
| 22 | where | ||
| 23 | D: ArchiveRead<IO = File>, | ||
| 24 | { | ||
| 25 | Self::read(File::open(path)?) | ||
| 26 | } | ||
| 27 | |||
| 28 | pub fn files(&self) -> Vec<&D::File> { | ||
| 29 | self.driver.files() | ||
| 30 | } | ||
| 31 | |||
| 32 | pub fn get_file(&self, name: &str) -> Option<&D::File> { | ||
| 33 | self.driver.get_file(name) | ||
| 34 | } | ||
| 18 | } | 35 | } |
| 19 | 36 | ||
| 20 | impl<D: ArchiveWrite> Archive<D> where D::IO: Read + Write {} | 37 | impl<D: ArchiveWrite> Archive<D> where D::IO: Read + Write {} |
diff --git a/src/driver/driver.rs b/src/driver/driver.rs index 3a8ed16..9c18e1f 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs | |||
| @@ -16,6 +16,12 @@ where | |||
| 16 | { | 16 | { |
| 17 | // Create driver instance | 17 | // Create driver instance |
| 18 | fn read(io: Self::IO) -> ArchiveResult<Self, Self::Error>; | 18 | fn read(io: Self::IO) -> ArchiveResult<Self, Self::Error>; |
| 19 | |||
| 20 | // Return vec of files (sorted by name) | ||
| 21 | fn files(&self) -> Vec<&Self::File>; | ||
| 22 | |||
| 23 | // Return file by name | ||
| 24 | fn get_file(&self, name: &str) -> Option<&Self::File>; | ||
| 19 | } | 25 | } |
| 20 | 26 | ||
| 21 | pub trait ArchiveWrite: ArchiveRead | 27 | pub trait ArchiveWrite: ArchiveRead |
diff --git a/src/zip/archive.rs b/src/zip/archive.rs new file mode 100644 index 0000000..9a244fc --- /dev/null +++ b/src/zip/archive.rs | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | use crate::{Archive, Zip}; | ||
| 2 | use std::io::{Read, Seek, Write}; | ||
| 3 | |||
| 4 | impl<IO: Read + Seek> Archive<Zip<IO>> { | ||
| 5 | pub fn comment(&self) -> &String { | ||
| 6 | self.driver.comment() | ||
| 7 | } | ||
| 8 | } | ||
| 9 | |||
| 10 | impl<IO: Read + Write + Seek> Archive<Zip<IO>> {} | ||
diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 8662623..650344e 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs | |||
| @@ -4,10 +4,9 @@ use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, | |||
| 4 | use crate::zip::{ZipError, ZipFile, ZipResult}; | 4 | use crate::zip::{ZipError, ZipFile, ZipResult}; |
| 5 | use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; | 5 | use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; |
| 6 | use std::collections::HashMap as Map; | 6 | use std::collections::HashMap as Map; |
| 7 | use std::fs::File; | ||
| 8 | use std::io::{Read, Seek, SeekFrom, Write}; | 7 | use std::io::{Read, Seek, SeekFrom, Write}; |
| 9 | 8 | ||
| 10 | pub struct Zip<IO = File> { | 9 | pub struct Zip<IO> { |
| 11 | io: IO, | 10 | io: IO, |
| 12 | 11 | ||
| 13 | files: Map<String, ZipFile>, | 12 | files: Map<String, ZipFile>, |
| @@ -169,10 +168,24 @@ impl<IO: Read + Seek> ArchiveRead for Zip<IO> { | |||
| 169 | 168 | ||
| 170 | Ok(Self { io, files, comment }) | 169 | Ok(Self { io, files, comment }) |
| 171 | } | 170 | } |
| 171 | |||
| 172 | fn files(&self) -> Vec<&Self::File> { | ||
| 173 | let mut files: Vec<&Self::File> = self.files.values().collect(); | ||
| 174 | files.sort_by_key(|f| &f.name); | ||
| 175 | files | ||
| 176 | } | ||
| 177 | |||
| 178 | fn get_file(&self, name: &str) -> Option<&Self::File> { | ||
| 179 | self.files.get(name) | ||
| 180 | } | ||
| 172 | } | 181 | } |
| 173 | 182 | ||
| 174 | impl<IO: Read + Seek> Zip<IO> {} | 183 | impl<IO: Read + Seek> Zip<IO> { |
| 184 | pub fn comment(&self) -> &String { | ||
| 185 | &self.comment | ||
| 186 | } | ||
| 187 | } | ||
| 175 | 188 | ||
| 176 | impl<IO: Read + Write + Seek> ArchiveWrite for Zip<IO> {} | 189 | impl<IO: Read + Write + Seek> ArchiveWrite for Zip<IO> {} |
| 177 | 190 | ||
| 178 | impl<IO: Read + Write> Zip<IO> {} | 191 | impl<IO: Read + Write + Seek> Zip<IO> {} |
diff --git a/src/zip/file.rs b/src/zip/file.rs index b4f2d7c..5b0723f 100644 --- a/src/zip/file.rs +++ b/src/zip/file.rs | |||
| @@ -29,7 +29,7 @@ impl CompressionMethod { | |||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub struct BitFlag { | 31 | pub struct BitFlag { |
| 32 | pub flag: u16, | 32 | flag: u16, |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | pub mod bit { | 35 | pub mod bit { |
diff --git a/src/zip/mod.rs b/src/zip/mod.rs index 23cadb9..89d748b 100644 --- a/src/zip/mod.rs +++ b/src/zip/mod.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | mod archive; | ||
| 1 | mod driver; | 2 | mod driver; |
| 2 | mod error; | 3 | mod error; |
| 3 | mod file; | 4 | mod file; |
| @@ -5,7 +6,7 @@ mod structs; | |||
| 5 | 6 | ||
| 6 | pub use driver::Zip; | 7 | pub use driver::Zip; |
| 7 | pub use error::{ZipError, ZipResult}; | 8 | pub use error::{ZipError, ZipResult}; |
| 8 | pub use file::ZipFile; | 9 | pub use file::{bit, BitFlag, CompressionMethod, ZipFile}; |
| 9 | 10 | ||
| 10 | #[cfg(test)] | 11 | #[cfg(test)] |
| 11 | mod tests; | 12 | mod tests; |
diff --git a/tests/files/zip.zip b/tests/files/zip.zip new file mode 100644 index 0000000..e17bbb7 --- /dev/null +++ b/tests/files/zip.zip | |||
| Binary files differ | |||
diff --git a/tests/zip.rs b/tests/zip.rs new file mode 100644 index 0000000..65244c1 --- /dev/null +++ b/tests/zip.rs | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | use archivator::{Archive, Zip}; | ||
| 2 | |||
| 3 | #[test] | ||
| 4 | fn test_zip() { | ||
| 5 | let archive = Archive::<Zip<_>>::read_from_file("tests/files/zip.zip").unwrap(); | ||
| 6 | |||
| 7 | assert_eq!(archive.comment(), "archive comment"); | ||
| 8 | assert_eq!( | ||
| 9 | archive | ||
| 10 | .files() | ||
| 11 | .iter() | ||
| 12 | .map(|f| &f.name) | ||
| 13 | .collect::<Vec<&String>>(), | ||
| 14 | vec!["a", "b", "c"] | ||
| 15 | ); | ||
| 16 | } | ||
