jagua_rs/probs/spp/entities/
instance.rs1use crate::entities::Item;
2use crate::probs::spp::entities::Strip;
3use crate::probs::spp::util::assertions;
4use itertools::Itertools;
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
8pub struct SPInstance {
10 pub items: Vec<(Arc<Item>, usize)>,
12 pub base_strip: Strip,
14}
15
16impl SPInstance {
17 #[must_use]
18 pub fn new(items: Vec<(Arc<Item>, usize)>, base_strip: Strip) -> Self {
19 assert!(
20 assertions::instance_item_indices_correct(&items),
21 "Item indices should match their positions"
22 );
23
24 assert!(items.iter().map(|(item, _)| item.external_id).all_unique());
25 Self { items, base_strip }
26 }
27
28 #[allow(clippy::cast_precision_loss)]
29 #[must_use]
30 pub fn item_area(&self) -> f32 {
31 self.items
32 .iter()
33 .map(|(item, qty)| item.shape_orig.area() * *qty as f32)
34 .sum()
35 }
36
37 #[must_use]
38 pub fn item_qty(&self, idx: usize) -> usize {
39 self.items[idx].1
40 }
41
42 #[must_use]
43 pub fn total_item_qty(&self) -> usize {
44 self.items.iter().map(|(_, qty)| *qty).sum()
45 }
46
47 #[must_use]
49 pub fn item(&self, idx: usize) -> &Arc<Item> {
50 &self.items[idx].0
51 }
52
53 #[must_use]
55 pub fn item_idx(&self, external_id: u64) -> Option<usize> {
56 self.items
57 .iter()
58 .find(|(item, _)| item.external_id == external_id)
59 .map(|(item, _)| item.idx)
60 }
61}