use crate::Bin;
pub trait OnlinePacker<Item> {
fn try_add(&mut self, item: Item) -> Result<Vec<Bin<Item>>, OnlinePackerError<Item>>;
fn add(&mut self, item: Item) -> Vec<Bin<Item>> {
match self.try_add(item) {
Ok(bins) => bins,
Err(_) => panic!("Could not add item to packer"),
}
}
fn finalize(self) -> Vec<Bin<Item>>;
fn pack_all<Iterable>(
self,
mut items: Iterable,
) -> Result<Vec<Bin<Item>>, (OnlinePackerError<Item>, Self, Iterable, Vec<Bin<Item>>)>
where
Self: Sized,
Iterable: Iterator<Item = Item>,
{
let mut closed_bins = Vec::new();
let mut packer = self;
while let Some(item) = items.next() {
match packer.try_add(item) {
Ok(closed) => closed_bins.extend(closed),
Err(err) => return Err((err, packer, items, closed_bins)),
}
}
closed_bins.extend(packer.finalize());
Ok(closed_bins)
}
}
#[derive(Debug)]
pub enum OnlinePackerError<T> {
ItemTooLarge(T),
}