From 6c31ce6e60790f31bf72094faaf4d57bdd63507a Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 1 Aug 2026 15:22:22 +0300 Subject: [PATCH] pdf-object: remove cross-reference entry wrapper Store cross-reference entries directly as CrossReferenceEntryType and move the constructors and query helpers onto the enum. Update parsing, repair, and object loading code to pattern-match entries without the redundant wrapper. Co-authored-by: Codex --- crates/pdf-document/src/object_loader.rs | 31 +++++------ crates/pdf-document/src/reader.rs | 6 +- .../src/object_collection.rs | 2 +- .../pdf-object/src/cross_reference_table.rs | 48 +++++++--------- .../pdf-parser/src/cross_reference_stream.rs | 20 +++---- .../pdf-parser/src/cross_reference_table.rs | 38 ++++++------- crates/pdf-parser/src/xref_builder.rs | 22 ++++---- crates/pdf-parser/tests/xref_builder.rs | 55 +++++++++---------- 8 files changed, 105 insertions(+), 117 deletions(-) diff --git a/crates/pdf-document/src/object_loader.rs b/crates/pdf-document/src/object_loader.rs index 7d2c7a7f..bd1265bf 100644 --- a/crates/pdf-document/src/object_loader.rs +++ b/crates/pdf-document/src/object_loader.rs @@ -19,8 +19,7 @@ use crate::error::PdfReaderError; use crate::object_stream::read_object_stream; use crate::reader::{EncryptionContext, object_id}; use pdf_object::{ - cross_reference_table::{CrossReferenceEntry, CrossReferenceEntryType}, - error::ObjectError, + cross_reference_table::CrossReferenceEntryType, error::ObjectError, object_variant::ObjectVariant, }; use pdf_object_collection::object_collection::ObjectCollection; @@ -45,12 +44,12 @@ struct LoadPlan { impl LoadPlan { /// Partitions live xref entries into normal objects and compressed-stream batches. - fn from_entries(entries: &BTreeMap) -> Self { + fn from_entries(entries: &BTreeMap) -> Self { let mut normal_objects = entries .values() - .filter_map(|entry| match entry.entry_type { - CrossReferenceEntryType::Normal { byte_offset, .. } if byte_offset != 0 => { - Some(byte_offset) + .filter_map(|entry| match entry { + CrossReferenceEntryType::Normal { byte_offset, .. } if *byte_offset != 0 => { + Some(*byte_offset) } _ => None, }) @@ -67,14 +66,14 @@ impl LoadPlan { let CrossReferenceEntryType::Compressed { object_stream_number, index_within_stream, - } = entry.entry_type + } = entry else { continue; }; compressed_streams - .entry(object_stream_number) + .entry(*object_stream_number) .or_default() - .entry(index_within_stream) + .entry(*index_within_stream) .or_default() .push(object_number); } @@ -264,7 +263,7 @@ pub(super) struct ObjectLoader<'input, 'loader> { impl<'input, 'loader> ObjectLoader<'input, 'loader> { /// Creates an object loader for one parsed cross-reference table. pub(super) fn new( - entries: &BTreeMap, + entries: &BTreeMap, parser: &'loader mut PdfParser<'input>, encryption: EncryptionContext, diagnostics: &'loader mut Vec, @@ -476,12 +475,12 @@ mod tests { #[test] fn load_plan_partitions_entries_and_groups_compressed_indexes() { let entries = BTreeMap::from([ - (0, CrossReferenceEntry::new_free(0, 65_535)), - (1, CrossReferenceEntry::new_normal(10, 0)), - (2, CrossReferenceEntry::new_compressed(5, 1)), - (3, CrossReferenceEntry::new_compressed(5, 1)), - (4, CrossReferenceEntry::new_normal(0, 0)), - (5, CrossReferenceEntry::new_normal(50, 0)), + (0, CrossReferenceEntryType::new_free(0, 65_535)), + (1, CrossReferenceEntryType::new_normal(10, 0)), + (2, CrossReferenceEntryType::new_compressed(5, 1)), + (3, CrossReferenceEntryType::new_compressed(5, 1)), + (4, CrossReferenceEntryType::new_normal(0, 0)), + (5, CrossReferenceEntryType::new_normal(50, 0)), ]); let plan = LoadPlan::from_entries(&entries); diff --git a/crates/pdf-document/src/reader.rs b/crates/pdf-document/src/reader.rs index d78b433b..dfa976b6 100644 --- a/crates/pdf-document/src/reader.rs +++ b/crates/pdf-document/src/reader.rs @@ -14,7 +14,7 @@ use pdf_object::object_id::PdfObjectId; use pdf_object::object_lookup::ObjectLookupExt; use pdf_object::object_resolver::{ObjectResolver, PassthroughResolver}; use pdf_object::{ - cross_reference_table::{CrossReferenceEntry, CrossReferenceTable}, + cross_reference_table::{CrossReferenceEntryType, CrossReferenceTable}, error::ObjectError, object_variant::ObjectVariant, trailer::Trailer, @@ -94,7 +94,7 @@ impl EncryptionContext { /// Creates decryption state from the trailer's optional encryption entry. fn from_trailer( trailer: &mut Trailer, - entries: &BTreeMap, + entries: &BTreeMap, parser: &mut PdfParser, password: &[u8], diagnostics: &mut Vec, @@ -171,7 +171,7 @@ fn extract_page_tree( /// Resolves and parses the trailer's encryption dictionary without decrypting it. fn load_encrypt_dictionary( encrypt_reference: ObjectVariant, - entries: &BTreeMap, + entries: &BTreeMap, parser: &mut PdfParser, ) -> Result { let object = match encrypt_reference { diff --git a/crates/pdf-object-collection/src/object_collection.rs b/crates/pdf-object-collection/src/object_collection.rs index 7e1013c2..52b3f775 100644 --- a/crates/pdf-object-collection/src/object_collection.rs +++ b/crates/pdf-object-collection/src/object_collection.rs @@ -216,7 +216,7 @@ impl ObjectCollection { ( k.to_string(), json!({ - "entry_type": format!("{:?}", v.entry_type) + "entry_type": format!("{v:?}") }), ) }) diff --git a/crates/pdf-object/src/cross_reference_table.rs b/crates/pdf-object/src/cross_reference_table.rs index 4fd4a791..cbb9ff0f 100644 --- a/crates/pdf-object/src/cross_reference_table.rs +++ b/crates/pdf-object/src/cross_reference_table.rs @@ -11,18 +11,18 @@ use crate::trailer::Trailer; #[derive(Debug, PartialEq, Clone)] pub struct CrossReferenceTable { /// The map of object numbers to cross-reference entries. - pub entries: BTreeMap, + pub entries: BTreeMap, /// The trailer associated with this cross-reference table. pub trailer: Trailer, } impl CrossReferenceTable { - pub fn new(entries: BTreeMap, trailer: Trailer) -> Self { + pub fn new(entries: BTreeMap, trailer: Trailer) -> Self { CrossReferenceTable { entries, trailer } } } -/// Distinguishes the type of a cross-reference entry. +/// Represents a cross-reference entry. #[derive(Debug, PartialEq, Clone)] pub enum CrossReferenceEntryType { /// Type 1: object at a byte offset in the file (traditional). @@ -42,42 +42,34 @@ pub enum CrossReferenceEntryType { }, } -#[derive(Debug, PartialEq, Clone)] -pub struct CrossReferenceEntry { - pub entry_type: CrossReferenceEntryType, -} - -impl CrossReferenceEntry { +impl CrossReferenceEntryType { + /// Creates a normal entry for an uncompressed object at a byte offset. pub fn new_normal(byte_offset: usize, generation_number: usize) -> Self { - CrossReferenceEntry { - entry_type: CrossReferenceEntryType::Normal { - byte_offset, - generation_number, - }, + CrossReferenceEntryType::Normal { + byte_offset, + generation_number, } } + /// Creates an entry for an object stored within a compressed object stream. pub fn new_compressed(object_stream_number: usize, index_within_stream: usize) -> Self { - CrossReferenceEntry { - entry_type: CrossReferenceEntryType::Compressed { - object_stream_number, - index_within_stream, - }, + CrossReferenceEntryType::Compressed { + object_stream_number, + index_within_stream, } } + /// Creates an entry for a free object. pub fn new_free(next_free_object: usize, generation_number: usize) -> Self { - CrossReferenceEntry { - entry_type: CrossReferenceEntryType::Free { - next_free_object, - generation_number, - }, + CrossReferenceEntryType::Free { + next_free_object, + generation_number, } } /// Returns the byte offset if this is a Normal entry. pub fn byte_offset(&self) -> Option { - match &self.entry_type { + match self { CrossReferenceEntryType::Normal { byte_offset, .. } => Some(*byte_offset), _ => None, } @@ -85,17 +77,17 @@ impl CrossReferenceEntry { /// Returns true if this is a Normal (in-use, uncompressed) entry. pub fn is_normal(&self) -> bool { - matches!(self.entry_type, CrossReferenceEntryType::Normal { .. }) + matches!(self, CrossReferenceEntryType::Normal { .. }) } /// Returns true if this is a Free entry. pub fn is_free(&self) -> bool { - matches!(self.entry_type, CrossReferenceEntryType::Free { .. }) + matches!(self, CrossReferenceEntryType::Free { .. }) } /// Returns true if this is a Compressed entry. pub fn is_compressed(&self) -> bool { - matches!(self.entry_type, CrossReferenceEntryType::Compressed { .. }) + matches!(self, CrossReferenceEntryType::Compressed { .. }) } } diff --git a/crates/pdf-parser/src/cross_reference_stream.rs b/crates/pdf-parser/src/cross_reference_stream.rs index 6ec06ba1..027ae6bb 100644 --- a/crates/pdf-parser/src/cross_reference_stream.rs +++ b/crates/pdf-parser/src/cross_reference_stream.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use pdf_object::{ - cross_reference_table::{CrossReferenceEntry, CrossReferenceTable}, + cross_reference_table::{CrossReferenceEntryType, CrossReferenceTable}, object_lookup::ObjectLookupExt, object_resolver::ObjectResolver, stream::StreamObject, @@ -162,7 +162,7 @@ impl<'data> XrefStreamEntryDecoder<'data> { } /// Returns the next complete entry, or `None` when the data is truncated. - fn next_entry(&mut self) -> Option { + fn next_entry(&mut self) -> Option { let end = self.position.saturating_add(self.layout.entry_width); let bytes = self.data.get(self.position..end)?; let entry = self.decode_entry(bytes)?; @@ -171,7 +171,7 @@ impl<'data> XrefStreamEntryDecoder<'data> { } /// Decodes one entry according to the `/W` field widths. - fn decode_entry(&self, bytes: &[u8]) -> Option { + fn decode_entry(&self, bytes: &[u8]) -> Option { let type_end = self.layout.type_width; let second_end = type_end.checked_add(self.layout.second_field_width)?; let third_end = second_end.checked_add(self.layout.third_field_width)?; @@ -189,10 +189,10 @@ impl<'data> XrefStreamEntryDecoder<'data> { let third_value = read_field(third_field); Some(match entry_type { - 0 => CrossReferenceEntry::new_free(second_value, third_value), - 1 => CrossReferenceEntry::new_normal(second_value, third_value), - 2 => CrossReferenceEntry::new_compressed(second_value, third_value), - _ => CrossReferenceEntry::new_free(0, 0), + 0 => CrossReferenceEntryType::new_free(second_value, third_value), + 1 => CrossReferenceEntryType::new_normal(second_value, third_value), + 2 => CrossReferenceEntryType::new_compressed(second_value, third_value), + _ => CrossReferenceEntryType::new_free(0, 0), }) } } @@ -284,7 +284,7 @@ mod tests { let e2 = &table.entries[&2]; assert!(e2.is_compressed()); - match &e2.entry_type { + match e2 { CrossReferenceEntryType::Compressed { object_stream_number, index_within_stream, @@ -349,7 +349,7 @@ mod tests { let table = parse_xref_stream(&stream, &PassthroughResolver).unwrap(); - assert_eq!(table.entries[&0], CrossReferenceEntry::new_free(0, 0)); + assert_eq!(table.entries[&0], CrossReferenceEntryType::new_free(0, 0)); } /// Builds a compressed xref stream with FlateDecode + PNG Up predictor, @@ -469,7 +469,7 @@ mod tests { let e3 = &table.entries[&3]; assert!(e3.is_compressed()); - match &e3.entry_type { + match e3 { CrossReferenceEntryType::Compressed { object_stream_number, index_within_stream, diff --git a/crates/pdf-parser/src/cross_reference_table.rs b/crates/pdf-parser/src/cross_reference_table.rs index 174b8e18..0667fd88 100644 --- a/crates/pdf-parser/src/cross_reference_table.rs +++ b/crates/pdf-parser/src/cross_reference_table.rs @@ -1,9 +1,7 @@ use std::collections::BTreeMap; use pdf_object::{ - cross_reference_table::{ - CrossReferenceEntry, CrossReferenceEntryType, CrossReferenceStatus, CrossReferenceTable, - }, + cross_reference_table::{CrossReferenceEntryType, CrossReferenceStatus, CrossReferenceTable}, object_resolver::ObjectResolver, }; use pdf_tokenizer::PdfToken; @@ -37,7 +35,7 @@ impl PdfParser<'_> { /// Parses the contiguous subsections that follow an `xref` keyword. pub(crate) fn parse_cross_reference_subsections( &mut self, - ) -> Result, ParserError> { + ) -> Result, ParserError> { let mut entries = BTreeMap::new(); loop { @@ -60,7 +58,7 @@ impl PdfParser<'_> { /// Parses one xref subsection header and its declared number of entries. fn parse_cross_reference_subsection( &mut self, - ) -> Result<(usize, Vec), ParserError> { + ) -> Result<(usize, Vec), ParserError> { let start_object_number = self.read_number::(true)?; self.skip_whitespace_and_comments(); let entry_count = self.read_number::(true)?; @@ -76,7 +74,7 @@ impl PdfParser<'_> { /// Parses a traditional xref row into its corresponding entry. pub(crate) fn parse_cross_reference_entry( &mut self, - ) -> Result { + ) -> Result { self.skip_whitespace_and_comments(); let field1 = self.read_number::(true)?; self.skip_whitespace_and_comments(); @@ -93,9 +91,9 @@ impl PdfParser<'_> { })?; Ok(match status { - CrossReferenceStatus::Normal => CrossReferenceEntry::new_normal(field1, field2), + CrossReferenceStatus::Normal => CrossReferenceEntryType::new_normal(field1, field2), CrossReferenceStatus::Free | CrossReferenceStatus::Old => { - CrossReferenceEntry::new_free(field1, field2) + CrossReferenceEntryType::new_free(field1, field2) } }) } @@ -105,8 +103,8 @@ impl PdfParser<'_> { /// leading free-object-zero pattern encountered in some PDFs. fn normalize_xref_subsection_entries( start_object_number: usize, - entries: Vec, -) -> Vec<(usize, CrossReferenceEntry)> { + entries: Vec, +) -> Vec<(usize, CrossReferenceEntryType)> { let has_leading_free_object_zero = start_object_number > 0 && entries .first() @@ -132,14 +130,12 @@ fn normalize_xref_subsection_entries( /// Returns whether an entry is the object-zero free entry incorrectly included /// at the start of a non-zero xref subsection. -fn is_malformed_leading_free_object_zero(entry: &CrossReferenceEntry) -> bool { +fn is_malformed_leading_free_object_zero(entry: &CrossReferenceEntryType) -> bool { matches!( entry, - CrossReferenceEntry { - entry_type: CrossReferenceEntryType::Free { - next_free_object: 0, - generation_number: 65_535, - } + CrossReferenceEntryType::Free { + next_free_object: 0, + generation_number: 65_535, } ) } @@ -271,8 +267,8 @@ mod tests { #[test] fn test_normalize_xref_subsection_entries_uses_declared_range() { let entries = vec![ - CrossReferenceEntry::new_normal(17, 0), - CrossReferenceEntry::new_normal(81, 0), + CrossReferenceEntryType::new_normal(17, 0), + CrossReferenceEntryType::new_normal(81, 0), ]; let normalized = normalize_xref_subsection_entries(4, entries); @@ -284,9 +280,9 @@ mod tests { #[test] fn test_normalize_xref_subsection_entries_handles_leading_free_object_zero() { let entries = vec![ - CrossReferenceEntry::new_free(0, 65_535), - CrossReferenceEntry::new_normal(17, 0), - CrossReferenceEntry::new_normal(81, 0), + CrossReferenceEntryType::new_free(0, 65_535), + CrossReferenceEntryType::new_normal(17, 0), + CrossReferenceEntryType::new_normal(81, 0), ]; let normalized = normalize_xref_subsection_entries(4, entries); diff --git a/crates/pdf-parser/src/xref_builder.rs b/crates/pdf-parser/src/xref_builder.rs index 1dcf891a..693c54e1 100644 --- a/crates/pdf-parser/src/xref_builder.rs +++ b/crates/pdf-parser/src/xref_builder.rs @@ -1,7 +1,7 @@ use std::collections::{BTreeMap, HashSet}; use pdf_object::{ - cross_reference_table::{CrossReferenceEntry, CrossReferenceEntryType, CrossReferenceTable}, + cross_reference_table::{CrossReferenceEntryType, CrossReferenceTable}, object_resolver::PassthroughResolver, object_variant::ObjectVariant, stream::StreamObject, @@ -158,8 +158,8 @@ impl<'parser, 'input> XrefBuilder<'parser, 'input> { /// Merges a parsed subsection into the accumulated object map. fn merge_entries( - entries: &mut BTreeMap, - section_entries: BTreeMap, + entries: &mut BTreeMap, + section_entries: BTreeMap, ) { for (object_number, entry) in section_entries { let _ = entries.entry(object_number).or_insert(entry); @@ -293,7 +293,7 @@ impl<'parser, 'input> XrefBuilder<'parser, 'input> { /// Finishes malformed parsing by reading the trailer and assembling the table. fn finish_malformed_section( &mut self, - entries: BTreeMap, + entries: BTreeMap, ) -> Result { if entries.is_empty() { return Err(self.invalid_xref_error()); @@ -307,7 +307,7 @@ impl<'parser, 'input> XrefBuilder<'parser, 'input> { } /// Probes a malformed row without consuming input on failure. - fn try_parse_malformed_entry(&mut self) -> Result { + fn try_parse_malformed_entry(&mut self) -> Result { let mark = self.parser.tokenizer.position; let result = self.parser.parse_cross_reference_entry(); if result.is_err() { @@ -481,7 +481,7 @@ impl<'parser, 'input> XrefBuilder<'parser, 'input> { let CrossReferenceEntryType::Normal { byte_offset, generation_number, - } = &entry.entry_type + } = entry else { continue; }; @@ -522,7 +522,9 @@ impl<'parser, 'input> XrefBuilder<'parser, 'input> { }); match recovered_offset { - Some(offset) => *entry = CrossReferenceEntry::new_normal(offset, generation_number), + Some(offset) => { + *entry = CrossReferenceEntryType::new_normal(offset, generation_number) + } None => invalid_entries.push(object_number), } } @@ -587,7 +589,7 @@ impl<'parser, 'input> XrefBuilder<'parser, 'input> { let CrossReferenceEntryType::Normal { byte_offset, generation_number, - } = &entry.entry_type + } = entry else { return true; }; @@ -633,7 +635,7 @@ impl PdfParser<'_> { #[cfg(test)] mod tests { - use pdf_object::cross_reference_table::CrossReferenceEntry; + use pdf_object::cross_reference_table::CrossReferenceEntryType; use super::*; @@ -665,7 +667,7 @@ mod tests { let entry = builder.try_parse_malformed_entry().unwrap(); - assert_eq!(entry, CrossReferenceEntry::new_normal(12, 34)); + assert_eq!(entry, CrossReferenceEntryType::new_normal(12, 34)); assert!(matches!( builder.parser.tokenizer.data().first().copied(), Some(b' ') | Some(b'\n') diff --git a/crates/pdf-parser/tests/xref_builder.rs b/crates/pdf-parser/tests/xref_builder.rs index 20d1d5a6..d6379589 100644 --- a/crates/pdf-parser/tests/xref_builder.rs +++ b/crates/pdf-parser/tests/xref_builder.rs @@ -9,8 +9,7 @@ use std::collections::BTreeMap; use pdf_object::{ - cross_reference_table::{CrossReferenceEntry, CrossReferenceEntryType}, - object_resolver::PassthroughResolver, + cross_reference_table::CrossReferenceEntryType, object_resolver::PassthroughResolver, object_variant::ObjectVariant, }; use pdf_parser::parser::PdfParser; @@ -425,7 +424,7 @@ fn build_xref_table_simple() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert!(table.entries.get(&0).expect("obj 0 should exist").is_free()); @@ -477,7 +476,7 @@ fn build_xref_table_falls_back_from_invalid_newer_xref() { table .entries .get(&2) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj2_offset) ); } @@ -526,14 +525,14 @@ fn build_xref_table_repairs_valid_section_with_shifted_entry_offsets() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert_eq!( table .entries .get(&5) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj5_offset) ); } @@ -568,21 +567,21 @@ fn build_xref_table_recovers_missing_xref_keyword_with_subsection_header() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert_eq!( table .entries .get(&2) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj2_offset) ); assert_eq!( table .entries .get(&3) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj3_offset) ); } @@ -620,14 +619,14 @@ fn build_xref_table_recovers_stripped_header_offsets() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert_eq!( table .entries .get(&2) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj2_offset) ); } @@ -668,21 +667,21 @@ fn build_xref_table_recovers_startxref_inside_endstream() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert_eq!( table .entries .get(&2) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj2_offset) ); assert_eq!( table .entries .get(&3) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj3_offset) ); assert!(bad_startxref_offset < xref_offset); @@ -733,35 +732,35 @@ fn build_xref_table_recovers_nearby_xref_without_line_boundary() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert_eq!( table .entries .get(&2) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj2_offset) ); assert_eq!( table .entries .get(&3) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj3_offset) ); assert_eq!( table .entries .get(&4) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj4_offset) ); assert_eq!( table .entries .get(&5) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj5_offset) ); } @@ -822,7 +821,7 @@ fn build_xref_table_repair_ignores_numeric_array_entries() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); } @@ -856,7 +855,7 @@ fn build_xref_table_merges_hybrid_xref_stream_entries() { let table = parser.build_xref_table().unwrap(); let pages_entry = table.entries.get(&2).expect("obj 2 should exist"); - match &pages_entry.entry_type { + match pages_entry { CrossReferenceEntryType::Compressed { object_stream_number, index_within_stream, @@ -868,7 +867,7 @@ fn build_xref_table_merges_hybrid_xref_stream_entries() { } let page_entry = table.entries.get(&3).expect("obj 3 should exist"); - match &page_entry.entry_type { + match page_entry { CrossReferenceEntryType::Compressed { object_stream_number, index_within_stream, @@ -890,14 +889,14 @@ fn build_xref_table_drops_invalid_normal_entry_from_xref_stream() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(9) ); assert!( table .entries .get(&6) - .and_then(CrossReferenceEntry::byte_offset) + .and_then(CrossReferenceEntryType::byte_offset) .is_some() ); assert!( @@ -963,21 +962,21 @@ fn build_xref_table_recovers_missing_xref_command() { table .entries .get(&1) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj1_offset) ); assert_eq!( table .entries .get(&3) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj3_offset) ); assert_eq!( table .entries .get(&5) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj5_offset) ); } @@ -1021,7 +1020,7 @@ fn build_xref_table_recovers_xref_keyword_with_flat_entries() { table .entries .get(&5) - .and_then(CrossReferenceEntry::byte_offset), + .and_then(CrossReferenceEntryType::byte_offset), Some(obj5_offset) ); }