From 93d3518c6fabc060c66e9868a8e259cc3fba48ed Mon Sep 17 00:00:00 2001 From: Amos Wenger Date: Fri, 2 Feb 2024 11:28:27 +0100 Subject: [PATCH] Rename 'reader' API to state machine api --- .github/workflows/test.yml | 2 +- Justfile | 2 +- rc-zip-tokio/src/entry_reader/mod.rs | 2 +- rc-zip/src/{reader.rs => reader/archive.rs} | 47 ++++++--------------- rc-zip/src/reader/entry.rs | 1 + rc-zip/src/reader/mod.rs | 24 +++++++++++ 6 files changed, 42 insertions(+), 36 deletions(-) rename rc-zip/src/{reader.rs => reader/archive.rs} (94%) create mode 100644 rc-zip/src/reader/entry.rs create mode 100644 rc-zip/src/reader/mod.rs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44ea5b7..d3176aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: cargo doc --all-features --no-deps - name: Run cargo clippy run: | - cargo hack clippy --feature-powerset --group-features deflate,deflate64,lzma,bzip2 + cargo hack clippy --each-feature - name: Run tests and collect coverage run: just ci-test - name: Upload coverage information diff --git a/Justfile b/Justfile index 75f16b4..3a0c6cf 100644 --- a/Justfile +++ b/Justfile @@ -4,7 +4,7 @@ _default: just --list check: - cargo hack clippy --feature-powerset --group-features deflate,deflate64,lzma,bzip2 + cargo hack clippy --each-feature # Run all tests locally test *args: diff --git a/rc-zip-tokio/src/entry_reader/mod.rs b/rc-zip-tokio/src/entry_reader/mod.rs index 2127c82..62a2dd1 100644 --- a/rc-zip-tokio/src/entry_reader/mod.rs +++ b/rc-zip-tokio/src/entry_reader/mod.rs @@ -284,7 +284,7 @@ fn method_to_decoder( if #[cfg(feature = "deflate")] { Box::new(deflate_dec::mk_decoder(raw_r)) } else { - return Err(Error::method_not_enabled(self.method)); + return Err(Error::method_not_enabled(method)); } } } diff --git a/rc-zip/src/reader.rs b/rc-zip/src/reader/archive.rs similarity index 94% rename from rc-zip/src/reader.rs rename to rc-zip/src/reader/archive.rs index 9fb822d..75c98a5 100644 --- a/rc-zip/src/reader.rs +++ b/rc-zip/src/reader/archive.rs @@ -1,19 +1,10 @@ +use super::FsmResult; use crate::{ encoding::Encoding, Archive, DirectoryHeader, EndOfCentralDirectory, EndOfCentralDirectory64Locator, EndOfCentralDirectory64Record, EndOfCentralDirectoryRecord, Error, FormatError, Located, StoredEntry, }; -macro_rules! transition { - ($state: expr => ($pattern: pat) $body: expr) => { - $state = if let $pattern = std::mem::take(&mut $state) { - $body - } else { - unreachable!() - }; - }; -} - use tracing::trace; use winnow::{ error::ErrMode, @@ -30,15 +21,6 @@ pub struct ArchiveReader { state: State, } -pub enum ArchiveReaderResult { - /// Indicates that [ArchiveReader][] has work left, and the loop should continue. - Continue, - /// Indicates that [ArchiveReader][] is done reading the central directory, - /// contains an [Archive][]. Calling any method after [process()](ArchiveReader::process()) has returned - /// `Done` will panic. - Done(Archive), -} - #[derive(Default)] enum State { /// Finding and reading the end of central directory record @@ -184,13 +166,12 @@ impl ArchiveReader { /// Errors returned from process() are caused by invalid zip archives, /// unsupported format quirks, or implementation bugs - never I/O errors. /// - /// A result of [ArchiveReaderResult::Continue] indicates one should loop again, + /// A result of [FsmResult::Continue] indicates one should loop again, /// starting with [wants_read()](ArchiveReader::wants_read()). /// - /// A result of [ArchiveReaderResult::Done] contains the [Archive], and indicates that no + /// A result of [FsmResult::Done] contains the [Archive], and indicates that no /// method should ever be called again on this reader. - pub fn process(&mut self) -> Result { - use ArchiveReaderResult as R; + pub fn process(&mut self) -> Result, Error> { use State as S; match self.state { S::ReadEocd { @@ -203,7 +184,7 @@ impl ArchiveReader { haystack_size, "ReadEocd | need more data" ); - return Ok(R::Continue); + return Ok(FsmResult::Continue); } match { @@ -235,14 +216,14 @@ impl ArchiveReader { directory_headers: vec![], } }); - Ok(R::Continue) + Ok(FsmResult::Continue) } else { trace!("ReadEocd | transition to ReadEocd64Locator"); transition!(self.state => (S::ReadEocd { mut buffer, .. }) { buffer.reset(); S::ReadEocd64Locator { buffer, eocdr } }); - Ok(R::Continue) + Ok(FsmResult::Continue) } } } @@ -252,7 +233,7 @@ impl ArchiveReader { match EndOfCentralDirectory64Locator::parser.parse_peek(input) { Err(ErrMode::Incomplete(_)) => { // need more data - Ok(R::Continue) + Ok(FsmResult::Continue) } Err(ErrMode::Backtrack(_)) | Err(ErrMode::Cut(_)) => { // we don't have a zip64 end of central directory locator - that's ok! @@ -266,7 +247,7 @@ impl ArchiveReader { directory_headers: vec![], } }); - Ok(R::Continue) + Ok(FsmResult::Continue) } Ok((_, locator)) => { trace!( @@ -281,7 +262,7 @@ impl ArchiveReader { eocdr, } }); - Ok(R::Continue) + Ok(FsmResult::Continue) } } } @@ -290,7 +271,7 @@ impl ArchiveReader { match EndOfCentralDirectory64Record::parser.parse_peek(input) { Err(ErrMode::Incomplete(_)) => { // need more data - Ok(R::Continue) + Ok(FsmResult::Continue) } Err(ErrMode::Backtrack(_)) | Err(ErrMode::Cut(_)) => { // at this point, we really expected to have a zip64 end @@ -310,7 +291,7 @@ impl ArchiveReader { directory_headers: vec![], } }); - Ok(R::Continue) + Ok(FsmResult::Continue) } } } @@ -422,7 +403,7 @@ impl ArchiveReader { } self.state = S::Done; - return Ok(R::Done(Archive { + return Ok(FsmResult::Done(Archive { size: self.size, comment, entries, @@ -445,7 +426,7 @@ impl ArchiveReader { buffer.consume(consumed); // need more data - Ok(R::Continue) + Ok(FsmResult::Continue) } S::Done { .. } => panic!("Called process() on ArchiveReader in Done state"), S::Transitioning => unreachable!(), diff --git a/rc-zip/src/reader/entry.rs b/rc-zip/src/reader/entry.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/rc-zip/src/reader/entry.rs @@ -0,0 +1 @@ + diff --git a/rc-zip/src/reader/mod.rs b/rc-zip/src/reader/mod.rs new file mode 100644 index 0000000..92fea0e --- /dev/null +++ b/rc-zip/src/reader/mod.rs @@ -0,0 +1,24 @@ +macro_rules! transition { + ($state: expr => ($pattern: pat) $body: expr) => { + $state = if let $pattern = std::mem::take(&mut $state) { + $body + } else { + unreachable!() + }; + }; +} + +mod archive; +pub use archive::ArchiveReader; + +mod entry; + +/// Indicates whether or not the state machine has completed its work +pub enum FsmResult { + /// Indicates that the state machine still has work to do, and + /// needs either data or a call to process + Continue, + /// Indicates that the state machine has completed its work, and + /// the result is the value provided + Done(T), +}