1use super::error::{GateError, Result};
2use super::traits::*;
3use super::types::GateNode;
4
5#[derive(Debug, Clone)]
6pub struct RectangleGateGeometry {
7 pub min: GateNode,
8 pub max: GateNode,
9}
10
11impl GateCenter for RectangleGateGeometry {
12 fn calculate_center(&self, x_param: &str, y_param: &str) -> Result<(f32, f32)> {
13 let min_x = self
14 .min
15 .get_coordinate(x_param)
16 .ok_or_else(|| GateError::missing_parameter(x_param, "rectangle min"))?;
17 let min_y = self
18 .min
19 .get_coordinate(y_param)
20 .ok_or_else(|| GateError::missing_parameter(y_param, "rectangle min"))?;
21 let max_x = self
22 .max
23 .get_coordinate(x_param)
24 .ok_or_else(|| GateError::missing_parameter(x_param, "rectangle max"))?;
25 let max_y = self
26 .max
27 .get_coordinate(y_param)
28 .ok_or_else(|| GateError::missing_parameter(y_param, "rectangle max"))?;
29
30 Ok(((min_x + max_x) / 2.0, (min_y + max_y) / 2.0))
31 }
32}
33
34impl GateContainment for RectangleGateGeometry {
35 fn contains_point(&self, x: f32, y: f32, x_param: &str, y_param: &str) -> Result<bool> {
36 let min_x = self
37 .min
38 .get_coordinate(x_param)
39 .ok_or_else(|| GateError::missing_parameter(x_param, "rectangle min"))?;
40 let min_y = self
41 .min
42 .get_coordinate(y_param)
43 .ok_or_else(|| GateError::missing_parameter(y_param, "rectangle min"))?;
44 let max_x = self
45 .max
46 .get_coordinate(x_param)
47 .ok_or_else(|| GateError::missing_parameter(x_param, "rectangle max"))?;
48 let max_y = self
49 .max
50 .get_coordinate(y_param)
51 .ok_or_else(|| GateError::missing_parameter(y_param, "rectangle max"))?;
52
53 Ok(x >= min_x && x <= max_x && y >= min_y && y <= max_y)
54 }
55}
56
57impl GateBounds for RectangleGateGeometry {
58 fn bounding_box(&self, x_param: &str, y_param: &str) -> Result<(f32, f32, f32, f32)> {
59 let min_x = self
60 .min
61 .get_coordinate(x_param)
62 .ok_or_else(|| GateError::missing_parameter(x_param, "rectangle min"))?;
63 let min_y = self
64 .min
65 .get_coordinate(y_param)
66 .ok_or_else(|| GateError::missing_parameter(y_param, "rectangle min"))?;
67 let max_x = self
68 .max
69 .get_coordinate(x_param)
70 .ok_or_else(|| GateError::missing_parameter(x_param, "rectangle max"))?;
71 let max_y = self
72 .max
73 .get_coordinate(y_param)
74 .ok_or_else(|| GateError::missing_parameter(y_param, "rectangle max"))?;
75
76 Ok((min_x, min_y, max_x, max_y))
77 }
78}
79
80impl GateValidation for RectangleGateGeometry {
81 fn is_valid(&self, x_param: &str, y_param: &str) -> Result<bool> {
82 if self.min.get_coordinate(x_param).is_none()
84 || self.min.get_coordinate(y_param).is_none()
85 || self.max.get_coordinate(x_param).is_none()
86 || self.max.get_coordinate(y_param).is_none()
87 {
88 return Ok(false);
89 }
90
91 let min_x = self.min.get_coordinate(x_param).unwrap();
93 let min_y = self.min.get_coordinate(y_param).unwrap();
94 let max_x = self.max.get_coordinate(x_param).unwrap();
95 let max_y = self.max.get_coordinate(y_param).unwrap();
96
97 Ok(min_x < max_x && min_y < max_y)
98 }
99}
100
101impl GateGeometryOps for RectangleGateGeometry {
102 fn gate_type_name(&self) -> &'static str {
103 "Rectangle"
104 }
105}