geometry/
shape.rs

1//! An enumeration of geometric shapes and their properties.
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    bbox::Bbox,
7    contains::{Containment, Contains},
8    point::Point,
9    polygon::Polygon,
10    rect::Rect,
11    transform::{TransformMut, TransformRef, Transformation, TranslateMut, TranslateRef},
12    union::BoundingUnion,
13};
14
15/// An enumeration of geometric shapes.
16#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
17pub enum Shape {
18    /// A rectangle.
19    Rect(Rect),
20    /// A polygon.
21    Polygon(Polygon),
22}
23
24impl Shape {
25    /// If this shape is a rectangle, returns the contained rectangle.
26    /// Otherwise, returns [`None`].
27    pub fn rect(&self) -> Option<Rect> {
28        match self {
29            Self::Rect(r) => Some(*r),
30            _ => None,
31        }
32    }
33
34    /// If this shape is a polygon, returns the contained polygon.
35    /// Otherwise, returns [`None`].
36    pub fn polygon(&self) -> Option<&Polygon> {
37        match self {
38            Self::Polygon(p) => Some(p),
39            _ => None,
40        }
41    }
42}
43
44impl TranslateRef for Shape {
45    #[inline]
46    fn translate_ref(&self, p: Point) -> Self {
47        match self {
48            Shape::Rect(rect) => Shape::Rect(rect.translate_ref(p)),
49            Shape::Polygon(polygon) => Shape::Polygon(polygon.translate_ref(p)),
50        }
51    }
52}
53
54impl TranslateMut for Shape {
55    #[inline]
56    fn translate_mut(&mut self, p: Point) {
57        match self {
58            Shape::Rect(rect) => rect.translate_mut(p),
59            Shape::Polygon(polygon) => polygon.translate_mut(p),
60        };
61    }
62}
63
64impl TransformRef for Shape {
65    #[inline]
66    fn transform_ref(&self, trans: Transformation) -> Self {
67        match self {
68            Shape::Rect(rect) => Shape::Rect(rect.transform_ref(trans)),
69            Shape::Polygon(polygon) => Shape::Polygon(polygon.transform_ref(trans)),
70        }
71    }
72}
73
74impl TransformMut for Shape {
75    #[inline]
76    fn transform_mut(&mut self, trans: crate::prelude::Transformation) {
77        match self {
78            Shape::Rect(rect) => rect.transform_mut(trans),
79            Shape::Polygon(polygon) => polygon.transform_mut(trans),
80        }
81    }
82}
83
84impl Bbox for Shape {
85    fn bbox(&self) -> Option<Rect> {
86        match self {
87            Shape::Rect(rect) => rect.bbox(),
88            Shape::Polygon(polygon) => polygon.bbox(),
89        }
90    }
91}
92
93impl From<Rect> for Shape {
94    #[inline]
95    fn from(value: Rect) -> Self {
96        Self::Rect(value)
97    }
98}
99
100impl From<Polygon> for Shape {
101    #[inline]
102    fn from(value: Polygon) -> Self {
103        Self::Polygon(value)
104    }
105}
106
107impl<T: Bbox> BoundingUnion<T> for Shape {
108    type Output = Option<Rect>;
109
110    fn bounding_union(&self, other: &T) -> Self::Output {
111        self.bbox().bounding_union(&other.bbox())
112    }
113}
114
115impl Contains<crate::point::Point> for Shape {
116    fn contains(&self, p: &crate::point::Point) -> Containment {
117        match self {
118            Shape::Rect(rect) => rect.contains(p),
119            Shape::Polygon(polygon) => polygon.contains(p),
120        }
121    }
122}