use crate::block::{Block, Dimension};
use crate::error::Result;
use crate::item::Item;
#[derive(Clone, Debug)]
pub struct Bin<'a> {
blocks: Vec<Block>,
pub items: Vec<Item<'a>>,
}
impl<'a> Bin<'a> {
pub fn new<F: Into<Dimension> + Copy>(dims: [F; 3]) -> Self {
Self {
blocks: vec![Block::new(dims[0], dims[1], dims[2])],
items: vec![],
}
}
pub fn fits(&self, item: &Item<'_>) -> bool {
self.blocks
.iter()
.any(|block| block.does_it_fit(&item.block))
}
pub fn try_packing(&mut self, item: Item<'a>) -> Option<()> {
let block_to_pack_index =
self.blocks
.iter()
.enumerate()
.find_map(|(block_index, block)| {
if block.does_it_fit(&item.block) {
Some(block_index)
} else {
None
}
})?;
let block_to_pack = self.blocks.remove(block_to_pack_index);
self.blocks.append(
&mut block_to_pack
.best_fit(&item.block)
.expect("Invalid state - the block doesn't fit the item."),
);
self.items.push(item);
Some(())
}
pub fn clone_as_empty_bin(&self) -> Self {
Self {
blocks: self.blocks.clone(),
items: vec![],
}
}
}