rectangle_pack/target_bin/
push_available_bin_section.rs1#![allow(missing_docs)]
8
9use crate::bin_section::BinSection;
10use crate::TargetBin;
11use core::fmt::{Display, Formatter, Result as FmtResult};
12
13impl TargetBin {
14 pub fn push_available_bin_section(
28 &mut self,
29 bin_section: BinSection,
30 ) -> Result<(), PushBinSectionError> {
31 if bin_section.x >= self.max_width
32 || bin_section.y >= self.max_height
33 || bin_section.z >= self.max_depth
34 {
35 return Err(PushBinSectionError::OutOfBounds(bin_section));
36 }
37
38 for available in self.available_bin_sections.iter() {
39 if available.overlaps(&bin_section) {
40 return Err(PushBinSectionError::Overlaps {
41 remaining_section: *available,
42 new_section: bin_section,
43 });
44 }
45 }
46
47 self.push_available_bin_section_unchecked(bin_section);
48
49 Ok(())
50 }
51
52 pub fn push_available_bin_section_unchecked(&mut self, bin_section: BinSection) {
60 self.available_bin_sections.push(bin_section);
61 }
62}
63
64#[derive(Debug)]
67pub enum PushBinSectionError {
68 OutOfBounds(BinSection),
70 Overlaps {
72 remaining_section: BinSection,
74 new_section: BinSection,
76 },
77}
78
79impl Display for PushBinSectionError {
80 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
81 match self {
82 PushBinSectionError::OutOfBounds(oob) => {
83 f.debug_tuple("BinSection").field(oob).finish()
84 }
85 PushBinSectionError::Overlaps {
86 remaining_section,
87 new_section,
88 } => f
89 .debug_struct("Overlaps")
90 .field("remaining_section", remaining_section)
91 .field("new_section", new_section)
92 .finish(),
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use crate::width_height_depth::WidthHeightDepth;
101
102 #[test]
105 fn error_if_bin_section_out_of_bounds() {
106 let mut bin = empty_bin();
107
108 let out_of_bounds = BinSection::new(101, 0, 0, WidthHeightDepth::new(1, 1, 1));
109
110 match bin.push_available_bin_section(out_of_bounds).err().unwrap() {
111 PushBinSectionError::OutOfBounds(err_bin_section) => {
112 assert_eq!(err_bin_section, out_of_bounds)
113 }
114 _ => panic!(),
115 };
116 }
117
118 #[test]
121 fn error_if_bin_section_overlaps_another_remaining_section() {
122 let mut bin = empty_bin();
123
124 let overlaps = BinSection::new(0, 0, 0, WidthHeightDepth::new(1, 1, 1));
125
126 match bin.push_available_bin_section(overlaps).err().unwrap() {
127 PushBinSectionError::Overlaps {
128 remaining_section: err_remaining_section,
129 new_section: err_new_section,
130 } => {
131 assert_eq!(err_new_section, overlaps);
132 assert_eq!(
133 err_remaining_section,
134 BinSection::new(0, 0, 0, WidthHeightDepth::new(100, 100, 1))
135 );
136 }
137 _ => panic!(),
138 }
139 }
140
141 #[test]
143 fn push_bin_section() {
144 let mut bin = full_bin();
145
146 let valid_section = BinSection::new(1, 2, 0, WidthHeightDepth::new(1, 1, 1));
147
148 assert_eq!(bin.available_bin_sections.len(), 0);
149 bin.push_available_bin_section(valid_section).unwrap();
150 assert_eq!(bin.available_bin_sections.len(), 1);
151
152 assert_eq!(bin.available_bin_sections[0], valid_section);
153 }
154
155 fn empty_bin() -> TargetBin {
156 TargetBin::new(100, 100, 1)
157 }
158
159 fn full_bin() -> TargetBin {
160 let mut bin = TargetBin::new(100, 100, 1);
161
162 bin.available_bin_sections.clear();
163
164 bin
165 }
166}