pub struct PartCollection { /* private fields */ }Expand description
Ordered, gap-aware collection of PartEntry values.
Parts are keyed by part_number and stored in a BTreeMap so iteration
is always in ascending order. A declared total can be provided up front via
PartCollection::with_total; if not, the collection tracks the highest
non-TOC part number it has seen so that
missing_parts still works once a total is implied
by the highest part observed.
§Example: collecting three parts
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::with_total(3);
for n in [1u32, 2, 3] {
coll.add(PartEntry { part_number: n, body_bytes: vec![], subject: None }).unwrap();
}
assert!(coll.is_complete());Implementations§
Source§impl PartCollection
impl PartCollection
Sourcepub fn new() -> Self
pub fn new() -> Self
Create an empty collection with no declared total.
The total will be inferred from the highest non-TOC part_number added
via add. Use with_total when the
total is known in advance (e.g. extracted from the subject line).
§Warning: is_complete() after a single add
Because the total is inferred from the highest part seen, adding a
single part (e.g. part 1) immediately sets total = Some(1) and
causes is_complete to return true. If the
actual series has more parts, this is a false positive. Prefer
with_total whenever the total is known.
§Example
use uuencoding_multi::PartCollection;
let coll = PartCollection::new();
assert!(coll.is_empty());
assert_eq!(coll.total(), None);Sourcepub fn with_total(total: u32) -> Self
pub fn with_total(total: u32) -> Self
Create an empty collection with a pre-declared total.
The total value sets the upper bound for gap detection: any part
number in 1..=total that has not been added will appear in
missing_parts.
If a later call to add supplies a part_number greater
than total, the stored total is bumped upward automatically.
§Note: total = 0
Passing total = 0 sets the expected part range to 1..=0, which is
empty. As a result missing_parts returns []
and is_complete returns true immediately,
before any parts are added. If you do not yet know the total, use
new instead.
§Example
use uuencoding_multi::PartCollection;
let coll = PartCollection::with_total(7);
assert_eq!(coll.total(), Some(7));
assert_eq!(coll.missing_parts().len(), 7); // parts 1–7 all missingSourcepub fn add(&mut self, entry: PartEntry) -> Result<(), MultiUuError>
pub fn add(&mut self, entry: PartEntry) -> Result<(), MultiUuError>
Add a part to the collection.
Returns MultiUuError::DuplicatePart if a part with the same
part_number is already present. The collection is left unchanged on
error.
If the incoming part_number is greater than the current total, the
stored total is bumped upward so that missing_parts
always covers every number up to the highest seen. TOC parts
(part_number = 0) do not affect the total.
§Errors
Returns MultiUuError::DuplicatePart when part_number is already
present in the collection.
§Example
use uuencoding_multi::{PartCollection, PartEntry, MultiUuError};
let mut coll = PartCollection::new();
coll.add(PartEntry { part_number: 1, body_bytes: vec![], subject: None }).unwrap();
// Adding the same part number again is an error.
let err = coll.add(PartEntry { part_number: 1, body_bytes: vec![], subject: None })
.unwrap_err();
assert!(matches!(err, MultiUuError::DuplicatePart { part_number: 1 }));Sourcepub fn total(&self) -> Option<u32>
pub fn total(&self) -> Option<u32>
Returns the declared total part count, or the highest non-TOC part number seen if no explicit total was provided.
Returns None only when the collection is empty and no total was set.
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::new();
assert_eq!(coll.total(), None);
coll.add(PartEntry { part_number: 3, body_bytes: vec![], subject: None }).unwrap();
assert_eq!(coll.total(), Some(3)); // inferred from highest part seenSourcepub fn present_parts(&self) -> impl Iterator<Item = u32> + '_
pub fn present_parts(&self) -> impl Iterator<Item = u32> + '_
Iterator over the part numbers that are present, in ascending order.
Includes the TOC part (part_number = 0) if one was added.
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::new();
coll.add(PartEntry { part_number: 3, body_bytes: vec![], subject: None }).unwrap();
coll.add(PartEntry { part_number: 1, body_bytes: vec![], subject: None }).unwrap();
let present: Vec<u32> = coll.present_parts().collect();
assert_eq!(present, vec![1, 3]); // always ascendingSourcepub fn missing_parts(&self) -> Vec<u32>
pub fn missing_parts(&self) -> Vec<u32>
Sorted list of part numbers in 1..=total that are absent from the
collection.
Returns an empty Vec when total is None.
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::with_total(4);
coll.add(PartEntry { part_number: 1, body_bytes: vec![], subject: None }).unwrap();
coll.add(PartEntry { part_number: 3, body_bytes: vec![], subject: None }).unwrap();
assert_eq!(coll.missing_parts(), vec![2, 4]);Sourcepub fn is_complete(&self) -> bool
pub fn is_complete(&self) -> bool
Returns true iff the total is known and every part in 1..=total is
present.
Always returns false when total is None, even if parts have been
added.
§Warning: auto-inferred total
When a collection was created with new (no declared
total), the total is inferred as the highest part number seen. Adding
only part 1 sets total = Some(1) and this function immediately returns
true, even if the series actually has more parts. Use
with_total to set the authoritative total.
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::with_total(2);
coll.add(PartEntry { part_number: 1, body_bytes: vec![], subject: None }).unwrap();
assert!(!coll.is_complete());
coll.add(PartEntry { part_number: 2, body_bytes: vec![], subject: None }).unwrap();
assert!(coll.is_complete());Sourcepub fn toc_part(&self) -> Option<&PartEntry>
pub fn toc_part(&self) -> Option<&PartEntry>
Returns the TOC part (part number 0) if one was added, None otherwise.
The TOC part body can be passed to parse_toc to
extract file metadata.
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::new();
assert!(coll.toc_part().is_none());
coll.add(PartEntry { part_number: 0, body_bytes: b"toc".to_vec(), subject: None }).unwrap();
assert!(coll.toc_part().is_some());Sourcepub fn get(&self, part_number: u32) -> Option<&PartEntry>
pub fn get(&self, part_number: u32) -> Option<&PartEntry>
Look up a part by its part number.
Returns None if the part is not present in the collection. Valid for
any part number including 0 (TOC).
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::new();
coll.add(PartEntry { part_number: 2, body_bytes: b"data".to_vec(), subject: None }).unwrap();
assert!(coll.get(2).is_some());
assert!(coll.get(1).is_none());Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Number of entries currently in the collection, including the TOC part
(part_number = 0) if present.
§Example
use uuencoding_multi::{PartCollection, PartEntry};
let mut coll = PartCollection::new();
assert_eq!(coll.len(), 0);
coll.add(PartEntry { part_number: 1, body_bytes: vec![], subject: None }).unwrap();
assert_eq!(coll.len(), 1);Trait Implementations§
Source§impl Clone for PartCollection
impl Clone for PartCollection
Source§fn clone(&self) -> PartCollection
fn clone(&self) -> PartCollection
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more