1use alloc::vec::Vec;
2use core::fmt;
3
4use memchr::memmem;
5
6use crate::headers::{Headers, ParseResult};
7
8pub struct File<'data> {
10 offsets: Vec<usize>,
11 data: &'data [u8],
12}
13
14impl<'data> File<'data> {
15 pub fn new(data: &'data [u8]) -> Self {
20 let offsets = memmem::find_iter(data, crate::MARKER).collect();
21 Self { offsets, data }
22 }
23
24 #[inline]
26 pub fn log_count(&self) -> usize {
27 self.offsets.len()
28 }
29
30 pub fn iter(&self) -> impl Iterator<Item = ParseResult<Headers<'data>>> + '_ {
36 self.offsets
37 .iter()
38 .map(|&offset| Headers::parse(&self.data[offset..]))
39 }
40
41 pub fn parse(&self, index: usize) -> Option<ParseResult<Headers<'data>>> {
44 let start = *self.offsets.get(index)?;
45 let data = if let Some(&next) = self.offsets.get(index + 1) {
46 &self.data[start..next]
47 } else {
48 &self.data[start..]
49 };
50
51 Some(Headers::parse(data))
52 }
53}
54
55impl fmt::Debug for File<'_> {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 f.debug_struct("File")
58 .field("offsets", &self.offsets)
59 .finish_non_exhaustive()
60 }
61}