Skip to main content

PartCollection

Struct PartCollection 

Source
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

Source

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).

§Example
use uuencoding_multi::PartCollection;

let coll = PartCollection::new();
assert!(coll.is_empty());
assert_eq!(coll.total(), None);
Source

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.

§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 missing
Source

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 }));
Source

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 seen
Source

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 ascending
Source

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]);
Source

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.

§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());
Source

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());
Source

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());
Source

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);
Source

pub fn is_empty(&self) -> bool

Returns true iff no parts have been added.

§Example
use uuencoding_multi::PartCollection;

let coll = PartCollection::new();
assert!(coll.is_empty());

Trait Implementations§

Source§

impl Default for PartCollection

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.