Skip to content

Commit

Permalink
✨ Add libpna::read_chunks_from_slice
Browse files Browse the repository at this point in the history
  • Loading branch information
ChanTsune committed Nov 21, 2024
1 parent 079112a commit 69f8e3d
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/src/archive/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
use futures_io::AsyncRead;
#[cfg(feature = "unstable-async")]
use futures_util::AsyncReadExt;
pub(crate) use slice::read_header_from_slice;
use std::{
collections::VecDeque,
io::{self, Read, Seek, SeekFrom},
Expand Down
2 changes: 1 addition & 1 deletion lib/src/archive/read/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use std::borrow::Cow;
use std::io;

fn read_header_from_slice(bytes: &[u8]) -> io::Result<&[u8]> {
pub(crate) fn read_header_from_slice(bytes: &[u8]) -> io::Result<&[u8]> {
// TODO: use split_at_checked instead
let (header, body) = bytes.split_at(PNA_HEADER.len());
if header != PNA_HEADER {
Expand Down
46 changes: 46 additions & 0 deletions lib/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,52 @@ pub fn read_as_chunks<R: Read>(
})
}

/// Read chunks from archive slice
///
/// # Example
///
/// ```
/// # use std::{io, fs};
/// use libpna::{prelude::*, read_chunks_from_slice};
/// # fn main() -> io::Result<()> {
/// let bytes = include_bytes!("../../resources/test/zstd.pna");
/// for chunk in read_chunks_from_slice(bytes)? {
/// let chunk = chunk?;
/// println!("chunk type: {}, chunk data size: {}", chunk.ty(), chunk.length());
/// }
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn read_chunks_from_slice<'s>(

Check warning

Code scanning / clippy

the following explicit lifetimes could be elided: 's Warning

the following explicit lifetimes could be elided: 's
archive: &'s [u8],

Check warning

Code scanning / clippy

the following explicit lifetimes could be elided: 's Warning

the following explicit lifetimes could be elided: 's
) -> io::Result<impl Iterator<Item = io::Result<impl Chunk + 's>>> {

Check warning

Code scanning / clippy

the following explicit lifetimes could be elided: 's Warning

the following explicit lifetimes could be elided: 's
struct Chunks<'a> {
reader: &'a [u8],
eoa: bool,
}
impl<'a> Iterator for Chunks<'a> {
type Item = io::Result<RawChunk<&'a [u8]>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.eoa {
return None;
}
Some(read_chunk_from_slice(self.reader).map(|(chunk, bytes)| {
self.eoa = chunk.ty() == ChunkType::AEND;
self.reader = bytes;
chunk
}))
}
}
let archive = crate::archive::read_header_from_slice(archive)?;

Ok(Chunks {
reader: archive,
eoa: false,
})
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 69f8e3d

Please sign in to comment.