aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Tolmachev <me@igorek.dev>2024-06-27 16:15:00 +0900
committerIgor Tolmachev <me@igorek.dev>2024-06-29 21:18:46 +0900
commit51694e1f0b2730915e0a57ec6d8de503cf06ef9a (patch)
tree165f3adbc29f96814b57aeba394fb4045af7c5f0 /src
parenta867677218c1d55dadfcac1ca5b8cd32a78a3c28 (diff)
downloadarchivator-51694e1f0b2730915e0a57ec6d8de503cf06ef9a.tar.gz
archivator-51694e1f0b2730915e0a57ec6d8de503cf06ef9a.zip
Create file driver and implement file reader
Diffstat (limited to 'src')
-rw-r--r--src/archive.rs20
-rw-r--r--src/driver/driver.rs27
-rw-r--r--src/driver/file.rs9
-rw-r--r--src/driver/mod.rs2
-rw-r--r--src/error.rs6
-rw-r--r--src/file.rs38
-rw-r--r--src/lib.rs3
-rw-r--r--src/zip/archive.rs4
-rw-r--r--src/zip/driver.rs38
-rw-r--r--src/zip/error.rs8
-rw-r--r--src/zip/file_driver.rs99
-rw-r--r--src/zip/file_info.rs (renamed from src/zip/file.rs)11
-rw-r--r--src/zip/mod.rs6
-rw-r--r--src/zip/tests.rs2
14 files changed, 224 insertions, 49 deletions
diff --git a/src/archive.rs b/src/archive.rs
index e635007..4a70867 100644
--- a/src/archive.rs
+++ b/src/archive.rs
@@ -1,5 +1,5 @@
1use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; 1use crate::driver::{ArchiveRead, ArchiveWrite, Driver};
2use crate::ArchiveResult; 2use crate::{ArchiveFile, ArchiveResult};
3use std::fs::File; 3use std::fs::File;
4use std::io::{Read, Write}; 4use std::io::{Read, Write};
5use std::path::Path; 5use std::path::Path;
@@ -10,9 +10,9 @@ pub struct Archive<D: Driver> {
10 10
11impl<D: ArchiveRead> Archive<D> 11impl<D: ArchiveRead> Archive<D>
12where 12where
13 D::IO: std::io::Read, 13 D::Io: std::io::Read,
14{ 14{
15 pub fn read(io: D::IO) -> ArchiveResult<Self, D::Error> { 15 pub fn read(io: D::Io) -> ArchiveResult<Self, D::Error> {
16 Ok(Self { 16 Ok(Self {
17 driver: D::read(io)?, 17 driver: D::read(io)?,
18 }) 18 })
@@ -20,18 +20,22 @@ where
20 20
21 pub fn read_from_file(path: impl AsRef<Path>) -> ArchiveResult<Self, D::Error> 21 pub fn read_from_file(path: impl AsRef<Path>) -> ArchiveResult<Self, D::Error>
22 where 22 where
23 D: ArchiveRead<IO = File>, 23 D: ArchiveRead<Io = File>,
24 { 24 {
25 Self::read(File::open(path)?) 25 Self::read(File::open(path)?)
26 } 26 }
27 27
28 pub fn files(&self) -> Vec<&D::File> { 28 pub fn files(&self) -> Vec<&D::FileInfo> {
29 self.driver.files() 29 self.driver.files()
30 } 30 }
31 31
32 pub fn get_file(&self, name: &str) -> Option<&D::File> { 32 pub fn get_file_info(&self, name: &str) -> Option<&D::FileInfo> {
33 self.driver.get_file(name) 33 self.driver.get_file_info(name)
34 }
35
36 pub fn get_file_reader<'d>(&'d mut self, name: &str) -> Option<ArchiveFile<D::FileDriver<'d>>> {
37 Some(ArchiveFile::new(self.driver.get_file_reader(name)?))
34 } 38 }
35} 39}
36 40
37impl<D: ArchiveWrite> Archive<D> where D::IO: Read + Write {} 41impl<D: ArchiveWrite> Archive<D> where D::Io: Read + Write {}
diff --git a/src/driver/driver.rs b/src/driver/driver.rs
index 9c18e1f..5bd2319 100644
--- a/src/driver/driver.rs
+++ b/src/driver/driver.rs
@@ -1,4 +1,4 @@
1use crate::driver::ArchiveFile; 1use crate::driver::{ArchiveFileInfo, FileDriver};
2use crate::ArchiveResult; 2use crate::ArchiveResult;
3use std::error::Error; 3use std::error::Error;
4use std::io::{Read, Write}; 4use std::io::{Read, Write};
@@ -6,26 +6,33 @@ use std::io::{Read, Write};
6pub trait Driver: Sized { 6pub trait Driver: Sized {
7 type Error: Error; 7 type Error: Error;
8 8
9 type IO; 9 type Io;
10 type File: ArchiveFile; 10 type FileInfo: ArchiveFileInfo;
11 type FileDriver<'d>: FileDriver
12 where
13 Self::FileInfo: 'd,
14 Self::Io: 'd;
11} 15}
12 16
13pub trait ArchiveRead: Driver 17pub trait ArchiveRead: Driver
14where 18where
15 Self::IO: Read, 19 Self::Io: Read,
16{ 20{
17 // Create driver instance 21 // Create driver instance
18 fn read(io: Self::IO) -> ArchiveResult<Self, Self::Error>; 22 fn read(io: Self::Io) -> ArchiveResult<Self, Self::Error>;
19 23
20 // Return vec of files (sorted by name) 24 // Return vec of files (sorted by name)
21 fn files(&self) -> Vec<&Self::File>; 25 fn files(&self) -> Vec<&Self::FileInfo>;
22 26
23 // Return file by name 27 // Return file info by name
24 fn get_file(&self, name: &str) -> Option<&Self::File>; 28 fn get_file_info(&self, name: &str) -> Option<&Self::FileInfo>;
29
30 // Return file reader by name
31 fn get_file_reader<'d>(&'d mut self, name: &str) -> Option<Self::FileDriver<'d>>;
25} 32}
26 33
27pub trait ArchiveWrite: ArchiveRead 34pub trait ArchiveWrite: Driver
28where 35where
29 Self::IO: Read + Write, 36 Self::Io: Read + Write,
30{ 37{
31} 38}
diff --git a/src/driver/file.rs b/src/driver/file.rs
index a4974f3..125c9c3 100644
--- a/src/driver/file.rs
+++ b/src/driver/file.rs
@@ -1 +1,8 @@
1pub trait ArchiveFile {} 1pub trait ArchiveFileInfo {}
2
3pub trait FileDriver {
4 type Io;
5 type FileInfo: ArchiveFileInfo;
6
7 fn info(&self) -> &Self::FileInfo;
8}
diff --git a/src/driver/mod.rs b/src/driver/mod.rs
index 36ee6b5..b637a34 100644
--- a/src/driver/mod.rs
+++ b/src/driver/mod.rs
@@ -2,4 +2,4 @@ mod driver;
2mod file; 2mod file;
3 3
4pub use driver::{ArchiveRead, ArchiveWrite, Driver}; 4pub use driver::{ArchiveRead, ArchiveWrite, Driver};
5pub use file::ArchiveFile; 5pub use file::{ArchiveFileInfo, FileDriver};
diff --git a/src/error.rs b/src/error.rs
index 7172d04..97a4e62 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -6,21 +6,21 @@ pub type ArchiveResult<T, E> = Result<T, ArchiveError<E>>;
6 6
7#[derive(Debug)] 7#[derive(Debug)]
8pub enum ArchiveError<E: Error> { 8pub enum ArchiveError<E: Error> {
9 IO { error: io::Error }, 9 Io { error: io::Error },
10 Serde { message: String }, 10 Serde { message: String },
11 Archivator { module: String, error: E }, 11 Archivator { module: String, error: E },
12} 12}
13 13
14impl<E: Error> From<io::Error> for ArchiveError<E> { 14impl<E: Error> From<io::Error> for ArchiveError<E> {
15 fn from(value: io::Error) -> Self { 15 fn from(value: io::Error) -> Self {
16 Self::IO { error: value } 16 Self::Io { error: value }
17 } 17 }
18} 18}
19 19
20impl<E: Error> Display for ArchiveError<E> { 20impl<E: Error> Display for ArchiveError<E> {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 match self { 22 match self {
23 Self::IO { error } => writeln!(f, "IO: {error}"), 23 Self::Io { error } => writeln!(f, "IO: {error}"),
24 Self::Serde { message } => writeln!(f, "Serde: {message}"), 24 Self::Serde { message } => writeln!(f, "Serde: {message}"),
25 Self::Archivator { module, error } => writeln!(f, "{module}: {error}"), 25 Self::Archivator { module, error } => writeln!(f, "{module}: {error}"),
26 } 26 }
diff --git a/src/file.rs b/src/file.rs
new file mode 100644
index 0000000..f284b98
--- /dev/null
+++ b/src/file.rs
@@ -0,0 +1,38 @@
1use crate::driver::FileDriver;
2use std::io::{Read, Result as IoResult, Seek, Write};
3
4pub struct ArchiveFile<D: FileDriver> {
5 pub(crate) driver: D,
6}
7
8impl<D: FileDriver> ArchiveFile<D> {
9 pub fn new(driver: D) -> Self {
10 Self { driver }
11 }
12
13 pub fn info(&self) -> &D::FileInfo {
14 self.driver.info()
15 }
16}
17
18impl<D: FileDriver + Read> Read for ArchiveFile<D> {
19 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
20 self.driver.read(buf)
21 }
22}
23
24impl<D: FileDriver + Write> Write for ArchiveFile<D> {
25 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
26 self.driver.write(buf)
27 }
28
29 fn flush(&mut self) -> IoResult<()> {
30 self.driver.flush()
31 }
32}
33
34impl<D: FileDriver + Seek> Seek for ArchiveFile<D> {
35 fn seek(&mut self, pos: std::io::SeekFrom) -> IoResult<u64> {
36 self.driver.seek(pos)
37 }
38}
diff --git a/src/lib.rs b/src/lib.rs
index c9cd1ad..26722c2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
1mod archive; 1mod archive;
2mod error; 2mod error;
3mod file;
3 4
4pub mod driver; 5pub mod driver;
5pub mod structs; 6pub mod structs;
@@ -7,4 +8,6 @@ pub mod zip;
7 8
8pub use archive::Archive; 9pub use archive::Archive;
9pub use error::{ArchiveError, ArchiveResult}; 10pub use error::{ArchiveError, ArchiveResult};
11pub use file::ArchiveFile;
12
10pub use zip::Zip; 13pub use zip::Zip;
diff --git a/src/zip/archive.rs b/src/zip/archive.rs
index 9a244fc..79e8ca1 100644
--- a/src/zip/archive.rs
+++ b/src/zip/archive.rs
@@ -1,10 +1,10 @@
1use crate::{Archive, Zip}; 1use crate::{Archive, Zip};
2use std::io::{Read, Seek, Write}; 2use std::io::{Read, Seek, Write};
3 3
4impl<IO: Read + Seek> Archive<Zip<IO>> { 4impl<Io: Read + Seek> Archive<Zip<Io>> {
5 pub fn comment(&self) -> &String { 5 pub fn comment(&self) -> &String {
6 self.driver.comment() 6 self.driver.comment()
7 } 7 }
8} 8}
9 9
10impl<IO: Read + Write + Seek> Archive<Zip<IO>> {} 10impl<Io: Read + Write + Seek> Archive<Zip<Io>> {}
diff --git a/src/zip/driver.rs b/src/zip/driver.rs
index 650344e..0db845d 100644
--- a/src/zip/driver.rs
+++ b/src/zip/driver.rs
@@ -1,27 +1,27 @@
1use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; 1use crate::driver::{ArchiveRead, ArchiveWrite, Driver};
2use crate::zip::file::{BitFlag, CompressionMethod};
3use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; 2use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64};
4use crate::zip::{ZipError, ZipFile, ZipResult}; 3use crate::zip::{BitFlag, CompressionMethod, ZipError, ZipFile, ZipFileInfo, ZipResult};
5use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; 4use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime};
6use std::collections::HashMap as Map; 5use std::collections::HashMap as Map;
7use std::io::{Read, Seek, SeekFrom, Write}; 6use std::io::{Read, Seek, SeekFrom, Write};
8 7
9pub struct Zip<IO> { 8pub struct Zip<Io> {
10 io: IO, 9 io: Io,
11 10
12 files: Map<String, ZipFile>, 11 files: Map<String, ZipFileInfo>,
13 comment: String, 12 comment: String,
14} 13}
15 14
16impl<IO> Driver for Zip<IO> { 15impl<Io> Driver for Zip<Io> {
17 type Error = ZipError; 16 type Error = ZipError;
18 17
19 type IO = IO; 18 type Io = Io;
20 type File = ZipFile; 19 type FileDriver<'d> = ZipFile<'d, Self::Io> where Self::Io: 'd;
20 type FileInfo = ZipFileInfo;
21} 21}
22 22
23impl<IO: Read + Seek> ArchiveRead for Zip<IO> { 23impl<Io: Read + Seek> ArchiveRead for Zip<Io> {
24 fn read(mut io: Self::IO) -> ZipResult<Self> { 24 fn read(mut io: Self::Io) -> ZipResult<Self> {
25 // Search eocdr 25 // Search eocdr
26 let limit = 65557.min(io.seek(SeekFrom::End(0))?) as i64; 26 let limit = 65557.min(io.seek(SeekFrom::End(0))?) as i64;
27 let start = io.seek(SeekFrom::End(-limit))?; 27 let start = io.seek(SeekFrom::End(-limit))?;
@@ -137,7 +137,7 @@ impl<IO: Read + Seek> ArchiveRead for Zip<IO> {
137 137
138 files.insert( 138 files.insert(
139 name.clone(), 139 name.clone(),
140 ZipFile::new( 140 ZipFileInfo::new(
141 CompressionMethod::from_struct_id(cdr.compression_method)?, 141 CompressionMethod::from_struct_id(cdr.compression_method)?,
142 BitFlag::new(cdr.bit_flag), 142 BitFlag::new(cdr.bit_flag),
143 NaiveDateTime::new( 143 NaiveDateTime::new(
@@ -169,23 +169,27 @@ impl<IO: Read + Seek> ArchiveRead for Zip<IO> {
169 Ok(Self { io, files, comment }) 169 Ok(Self { io, files, comment })
170 } 170 }
171 171
172 fn files(&self) -> Vec<&Self::File> { 172 fn files(&self) -> Vec<&Self::FileInfo> {
173 let mut files: Vec<&Self::File> = self.files.values().collect(); 173 let mut files: Vec<&Self::FileInfo> = self.files.values().collect();
174 files.sort_by_key(|f| &f.name); 174 files.sort_by_key(|f| &f.name);
175 files 175 files
176 } 176 }
177 177
178 fn get_file(&self, name: &str) -> Option<&Self::File> { 178 fn get_file_info(&self, name: &str) -> Option<&Self::FileInfo> {
179 self.files.get(name) 179 self.files.get(name)
180 } 180 }
181
182 fn get_file_reader<'d>(&'d mut self, name: &str) -> Option<Self::FileDriver<'d>> {
183 Some(ZipFile::new(&mut self.io, self.files.get(name)?).unwrap())
184 }
181} 185}
182 186
183impl<IO: Read + Seek> Zip<IO> { 187impl<Io: Read + Seek> Zip<Io> {
184 pub fn comment(&self) -> &String { 188 pub fn comment(&self) -> &String {
185 &self.comment 189 &self.comment
186 } 190 }
187} 191}
188 192
189impl<IO: Read + Write + Seek> ArchiveWrite for Zip<IO> {} 193impl<Io: Read + Write + Seek> ArchiveWrite for Zip<Io> {}
190 194
191impl<IO: Read + Write + Seek> Zip<IO> {} 195impl<Io: Read + Write + Seek> Zip<Io> {}
diff --git a/src/zip/error.rs b/src/zip/error.rs
index 1c5527c..d82de78 100644
--- a/src/zip/error.rs
+++ b/src/zip/error.rs
@@ -8,6 +8,7 @@ pub type ZipResult<T> = ArchiveResult<T, ZipError>;
8pub enum ZipError { 8pub enum ZipError {
9 EOCDRNotFound, 9 EOCDRNotFound,
10 InvalidEOCDR64Signature, 10 InvalidEOCDR64Signature,
11 InvalidFileHeaderSignature,
11 InvalidCDRSignature, 12 InvalidCDRSignature,
12 13
13 InvalidArchiveComment, 14 InvalidArchiveComment,
@@ -17,6 +18,8 @@ pub enum ZipError {
17 InvalidTime, 18 InvalidTime,
18 InvalidFileName, 19 InvalidFileName,
19 InvalidFileComment, 20 InvalidFileComment,
21
22 NegativeFileOffset,
20} 23}
21 24
22impl From<ZipError> for ArchiveError<ZipError> { 25impl From<ZipError> for ArchiveError<ZipError> {
@@ -38,6 +41,9 @@ impl Display for ZipError {
38 "Invalid signature of zip64 end of central directory record" 41 "Invalid signature of zip64 end of central directory record"
39 ) 42 )
40 } 43 }
44 Self::InvalidFileHeaderSignature => {
45 write!(f, "Invalid file header signature")
46 }
41 Self::InvalidCDRSignature => { 47 Self::InvalidCDRSignature => {
42 write!(f, "Invalid signature of central directory record") 48 write!(f, "Invalid signature of central directory record")
43 } 49 }
@@ -49,6 +55,8 @@ impl Display for ZipError {
49 Self::InvalidTime => write!(f, "Invalid time"), 55 Self::InvalidTime => write!(f, "Invalid time"),
50 Self::InvalidFileName => write!(f, "Invalid file name"), 56 Self::InvalidFileName => write!(f, "Invalid file name"),
51 Self::InvalidFileComment => write!(f, "Invalid file comment"), 57 Self::InvalidFileComment => write!(f, "Invalid file comment"),
58
59 Self::NegativeFileOffset => write!(f, "Negative file offset"),
52 } 60 }
53 } 61 }
54} 62}
diff --git a/src/zip/file_driver.rs b/src/zip/file_driver.rs
new file mode 100644
index 0000000..47b4242
--- /dev/null
+++ b/src/zip/file_driver.rs
@@ -0,0 +1,99 @@
1use crate::driver::FileDriver;
2use crate::zip::{ZipError, ZipFileInfo, ZipResult};
3use std::io::{
4 Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, Take,
5 Write,
6};
7
8pub struct ZipFile<'d, Io> {
9 io: &'d mut Io,
10 info: &'d ZipFileInfo,
11
12 bounds: (u64, u64),
13 cursor: u64,
14}
15
16impl<'d, Io> FileDriver for ZipFile<'d, Io> {
17 type Io = Io;
18 type FileInfo = ZipFileInfo;
19
20 fn info(&self) -> &Self::FileInfo {
21 self.info
22 }
23}
24
25impl<'d, Io: Read + Seek> ZipFile<'d, Io> {
26 pub fn new(io: &'d mut Io, info: &'d ZipFileInfo) -> ZipResult<Self> {
27 io.seek(SeekFrom::Start(info.header_pointer))?;
28 let buf = {
29 let mut buf = [0; 30];
30 io.read(&mut buf)?;
31 buf
32 };
33 if u32::from_le_bytes(buf[..4].try_into().unwrap()) != 0x04034b50 {
34 return Err(ZipError::InvalidFileHeaderSignature.into());
35 }
36 let data_pointer = info.header_pointer
37 + 30
38 + u16::from_le_bytes(buf[26..28].try_into().unwrap()) as u64
39 + u16::from_le_bytes(buf[28..30].try_into().unwrap()) as u64;
40 io.seek(SeekFrom::Start(data_pointer))?;
41
42 Ok(Self {
43 io,
44 info,
45
46 bounds: (data_pointer, data_pointer + info.compressed_size),
47 cursor: data_pointer,
48 })
49 }
50}
51
52impl<'d, Io: Read> Read for ZipFile<'d, Io> {
53 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
54 let upper = buf.len().min((self.bounds.1 - self.cursor) as usize);
55 self.cursor += upper as u64;
56 self.io.read(&mut buf[..upper])
57 }
58}
59
60impl<'d, Io: Write> Write for ZipFile<'d, Io> {
61 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
62 todo!()
63 }
64
65 fn flush(&mut self) -> IoResult<()> {
66 todo!()
67 }
68}
69
70impl<'d, Io: Seek> Seek for ZipFile<'d, Io> {
71 fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> {
72 self.cursor = match pos {
73 SeekFrom::Start(offset) => self.bounds.0 + offset,
74 SeekFrom::End(offset) => {
75 let cursor = self.bounds.1.saturating_add_signed(offset);
76 if cursor < self.bounds.0 {
77 return Err(IoError::new(
78 IoErrorKind::InvalidInput,
79 ZipError::NegativeFileOffset,
80 ));
81 }
82 cursor
83 }
84 SeekFrom::Current(offset) => {
85 let cursor = self.cursor.saturating_add_signed(offset);
86 if cursor < self.bounds.0 {
87 return Err(IoError::new(
88 IoErrorKind::InvalidInput,
89 ZipError::NegativeFileOffset,
90 ));
91 }
92 cursor
93 }
94 }
95 .min(self.bounds.1);
96
97 Ok(self.io.seek(SeekFrom::Start(self.cursor))? - self.bounds.0)
98 }
99}
diff --git a/src/zip/file.rs b/src/zip/file_info.rs
index 5b0723f..88322be 100644
--- a/src/zip/file.rs
+++ b/src/zip/file_info.rs
@@ -1,7 +1,8 @@
1use crate::driver::ArchiveFile; 1use crate::driver::ArchiveFileInfo;
2use crate::zip::{ZipError, ZipResult}; 2use crate::zip::{ZipError, ZipResult};
3use chrono::{DateTime, Local}; 3use chrono::{DateTime, Local};
4 4
5#[derive(Debug)]
5pub enum CompressionMethod { 6pub enum CompressionMethod {
6 Store, 7 Store,
7 Deflate, 8 Deflate,
@@ -28,6 +29,7 @@ impl CompressionMethod {
28 } 29 }
29} 30}
30 31
32#[derive(Debug)]
31pub struct BitFlag { 33pub struct BitFlag {
32 flag: u16, 34 flag: u16,
33} 35}
@@ -119,7 +121,8 @@ impl BitFlag {
119 } 121 }
120} 122}
121 123
122pub struct ZipFile { 124#[derive(Debug)]
125pub struct ZipFileInfo {
123 pub compression_method: CompressionMethod, 126 pub compression_method: CompressionMethod,
124 pub bit_flag: BitFlag, 127 pub bit_flag: BitFlag,
125 pub datetime: DateTime<Local>, 128 pub datetime: DateTime<Local>,
@@ -131,7 +134,7 @@ pub struct ZipFile {
131 pub comment: String, 134 pub comment: String,
132} 135}
133 136
134impl ZipFile { 137impl ZipFileInfo {
135 pub fn new( 138 pub fn new(
136 compression_method: CompressionMethod, 139 compression_method: CompressionMethod,
137 bit_flag: BitFlag, 140 bit_flag: BitFlag,
@@ -157,4 +160,4 @@ impl ZipFile {
157 } 160 }
158} 161}
159 162
160impl ArchiveFile for ZipFile {} 163impl ArchiveFileInfo for ZipFileInfo {}
diff --git a/src/zip/mod.rs b/src/zip/mod.rs
index 89d748b..3fe8384 100644
--- a/src/zip/mod.rs
+++ b/src/zip/mod.rs
@@ -1,12 +1,14 @@
1mod archive; 1mod archive;
2mod driver; 2mod driver;
3mod error; 3mod error;
4mod file; 4mod file_driver;
5mod file_info;
5mod structs; 6mod structs;
6 7
7pub use driver::Zip; 8pub use driver::Zip;
8pub use error::{ZipError, ZipResult}; 9pub use error::{ZipError, ZipResult};
9pub use file::{bit, BitFlag, CompressionMethod, ZipFile}; 10pub use file_driver::ZipFile;
11pub use file_info::{bit, BitFlag, CompressionMethod, ZipFileInfo};
10 12
11#[cfg(test)] 13#[cfg(test)]
12mod tests; 14mod tests;
diff --git a/src/zip/tests.rs b/src/zip/tests.rs
index d64e626..05e076d 100644
--- a/src/zip/tests.rs
+++ b/src/zip/tests.rs
@@ -1,4 +1,4 @@
1use crate::zip::file::{bit::DeflateMode, BitFlag}; 1use crate::zip::file_info::{bit::DeflateMode, BitFlag};
2 2
3#[test] 3#[test]
4fn test_bit_flag() { 4fn test_bit_flag() {