flow_gates/
rectangle.rs

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        // Must have valid coordinates
83        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        // Min must be less than max
92        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}