Lines
14.46 %
Functions
10.92 %
Branches
0 %
use std::{
fmt::Debug,
ops::{Add, Div, Mul, Sub},
};
use num_traits::{NumCast, One, Zero};
use crate::{
Ceil, DisplayScale, Displayable, Figure, Floor, Pixels, Point, Points, Round, Scale, Scaled,
Size, Vector, Vectorlike,
/// A 2d rectangle. This type may internally be represented with a [`SizedRect`]
/// or an [`ExtentsRect`]. All rect types implement [`Rectlike`].
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Rect<T, Unit> {
/// A [`SizedRect`].
Sized(SizedRect<T, Unit>),
/// An [`ExtentsRect`].
Extents(ExtentsRect<T, Unit>),
}
impl<T, Unit> Debug for Rect<T, Unit>
where
T: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Rect::Sized(sized) => sized.fmt(f),
Rect::Extents(extents) => extents.fmt(f),
impl<T, Unit> From<SizedRect<T, Unit>> for Rect<T, Unit> {
fn from(rect: SizedRect<T, Unit>) -> Self {
Self::Sized(rect)
impl<T: Default, Unit> From<Size<T, Unit>> for Rect<T, Unit> {
fn from(size: Size<T, Unit>) -> Self {
Self::Sized(SizedRect::from(size))
impl<T, Unit> From<ExtentsRect<T, Unit>> for Rect<T, Unit> {
fn from(rect: ExtentsRect<T, Unit>) -> Self {
Self::Extents(rect)
impl<T, Unit> Rect<T, Unit> {
/// Returns a new rect using `origin` and `size`.
pub fn sized(origin: Point<T, Unit>, size: Size<T, Unit>) -> Self {
Self::Sized(SizedRect::new(origin, size))
/// Returns a new rect using points `origin` and `extent`.
pub fn extents(origin: Point<T, Unit>, extent: Point<T, Unit>) -> Self {
Self::Extents(ExtentsRect::new(origin, extent))
impl<T, Unit> Rect<T, Unit>
T: NumCast + Copy,
/// Attempts to cast `T` to `NewT`. If unsuccessful, None is returned.
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<Rect<NewT, Unit>> {
Some(match self {
Self::Sized(sized) => Rect::Sized(sized.try_cast()?),
Self::Extents(extents) => Rect::Extents(extents.try_cast()?),
})
/// Casts `T` to `NewT`.
///
/// # Panics
/// Panics if casting fails.
pub fn cast<NewT: NumCast + Copy>(&self) -> Rect<NewT, Unit> {
self.try_cast().expect("unable to cast")
T: Copy,
/// Returns this value with the new unit. Does not affect the underlying
/// value.
pub fn cast_unit<NewUnit>(&self) -> Rect<T, NewUnit> {
Self::Sized(sized) => Rect::Sized(sized.cast_unit()),
Self::Extents(extents) => Rect::Extents(extents.cast_unit()),
impl<T, Unit> Copy for Rect<T, Unit> where T: Copy {}
impl<T, Unit> Clone for Rect<T, Unit>
T: Clone,
fn clone(&self) -> Self {
Self::Sized(sized) => Self::Sized(sized.clone()),
Self::Extents(extents) => Self::Extents(extents.clone()),
impl<T, Unit> Eq for Rect<T, Unit> where
T: Zero
+ PartialOrd
+ Mul<T, Output = T>
+ Sub<T, Output = T>
+ One
+ Add<T, Output = T>
+ Div<T, Output = T>
+ Copy
impl<T, Unit> PartialEq for Rect<T, Unit>
+ Copy,
fn eq(&self, other: &Self) -> bool {
Self::Sized(sized) => sized.eq(&other.as_sized()),
Self::Extents(extents) => extents.eq(&other.as_extents()),
impl<T, Unit> Default for Rect<T, Unit>
T: Default,
fn default() -> Self {
Self::Sized(SizedRect::default())
impl<T, Unit> Round for Rect<T, Unit>
T: Round,
fn round(self) -> Self {
Self::Sized(sized) => Self::Sized(sized.round()),
Self::Extents(extents) => Self::Extents(extents.round()),
impl<T, Unit> Ceil for Rect<T, Unit>
T: Ceil,
fn ceil(self) -> Self {
Self::Sized(sized) => Self::Sized(sized.ceil()),
Self::Extents(extents) => Self::Extents(extents.ceil()),
impl<T, Unit> Floor for Rect<T, Unit>
T: Floor,
fn floor(self) -> Self {
Self::Sized(sized) => Self::Sized(sized.floor()),
Self::Extents(extents) => Self::Extents(extents.floor()),
T: Ceil + Floor,
/// Returns a new rectangle that rounds the origin down using `floor` and
/// rounds the extent/size out using `ceil`.
pub fn round_out(self) -> Self {
Self::Sized(sized) => Self::Sized(sized.round_out()),
Self::Extents(extents) => Self::Extents(extents.round_out()),
/// Returns a new rectangle that rounds the origin up using `ceil` and
/// rounds the extent/size in using `floor`.
pub fn round_in(self) -> Self {
Self::Sized(sized) => Self::Sized(sized.round_in()),
Self::Extents(extents) => Self::Extents(extents.round_in()),
impl<T, UnitA, UnitB> Mul<Scale<T, UnitA, UnitB>> for Rect<T, UnitA>
T: Mul<T, Output = T> + Copy,
type Output = Rect<T, UnitB>;
fn mul(self, rhs: Scale<T, UnitA, UnitB>) -> Self::Output {
Self::Sized(sized) => Rect::Sized(sized * rhs),
Self::Extents(extents) => Rect::Extents(extents * rhs),
impl<T, UnitA, UnitB> Div<crate::Scale<T, UnitA, UnitB>> for Rect<T, UnitB>
T: Div<T, Output = T> + Copy,
type Output = Rect<T, UnitA>;
fn div(self, rhs: crate::Scale<T, UnitA, UnitB>) -> Self::Output {
Self::Sized(sized) => Rect::Sized(sized / rhs),
Self::Extents(extents) => Rect::Extents(extents / rhs),
impl<T, Unit> crate::Approx<T> for Rect<T, Unit>
T: approx::AbsDiffEq
+ Zero
fn approx_eq(&self, other: &Self) -> bool {
Self::Sized(sized) => sized.approx_eq(&other.as_sized()),
Self::Extents(extents) => extents.approx_eq(&other.as_extents()),
impl<T, Unit> approx::AbsDiffEq for Rect<T, Unit>
T: approx::AbsDiffEq<Epsilon = T>
type Epsilon = T::Epsilon;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
Self::Sized(sized) => sized.abs_diff_eq(&other.as_sized(), epsilon),
Self::Extents(extents) => extents.abs_diff_eq(&other.as_extents(), epsilon),
fn abs_diff_ne(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
Self::Sized(sized) => sized.abs_diff_ne(&other.as_sized(), epsilon),
Self::Extents(extents) => extents.abs_diff_ne(&other.as_extents(), epsilon),
impl<T, Unit> approx::UlpsEq for Rect<T, Unit>
T: approx::UlpsEq<Epsilon = T>
fn default_max_ulps() -> u32 {
T::default_max_ulps()
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
Self::Sized(sized) => sized.ulps_eq(&other.as_sized(), epsilon, max_ulps),
Self::Extents(extents) => extents.ulps_eq(&other.as_extents(), epsilon, max_ulps),
fn ulps_ne(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
Self::Sized(sized) => sized.ulps_ne(&other.as_sized(), epsilon, max_ulps),
Self::Extents(extents) => extents.ulps_ne(&other.as_extents(), epsilon, max_ulps),
impl<T, Unit> approx::RelativeEq for Rect<T, Unit>
T: approx::RelativeEq<Epsilon = T>
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
Self::Sized(sized) => sized.relative_eq(&other.as_sized(), epsilon, max_relative),
Self::Extents(extents) => {
extents.relative_eq(&other.as_extents(), epsilon, max_relative)
fn relative_ne(
Self::Sized(sized) => sized.relative_ne(&other.as_sized(), epsilon, max_relative),
extents.relative_ne(&other.as_extents(), epsilon, max_relative)
impl<T> Displayable<T> for Rect<T, Scaled>
T: Div<T, Output = T> + Mul<T, Output = T> + Copy,
type Pixels = Rect<T, Pixels>;
type Points = Rect<T, Points>;
type Scaled = Self;
fn to_pixels(&self, scale: &DisplayScale<T>) -> Self::Pixels {
Self::Sized(sized) => Rect::Sized(sized.to_pixels(scale)),
Self::Extents(extents) => Rect::Extents(extents.to_pixels(scale)),
fn to_points(&self, scale: &DisplayScale<T>) -> Self::Points {
Self::Sized(sized) => Rect::Sized(sized.to_points(scale)),
Self::Extents(extents) => Rect::Extents(extents.to_points(scale)),
fn to_scaled(&self, _scale: &DisplayScale<T>) -> Self::Scaled {
*self
impl<T> Displayable<T> for Rect<T, Points>
type Points = Self;
type Scaled = Rect<T, Scaled>;
fn to_points(&self, _scale: &DisplayScale<T>) -> Self::Points {
fn to_scaled(&self, scale: &DisplayScale<T>) -> Self::Scaled {
Self::Sized(sized) => Rect::Sized(sized.to_scaled(scale)),
Self::Extents(extents) => Rect::Extents(extents.to_scaled(scale)),
impl<T> Displayable<T> for Rect<T, Pixels>
type Pixels = Self;
fn to_pixels(&self, _scale: &DisplayScale<T>) -> Self::Pixels {
/// A rectangle that uses a [`Point`] and a [`Size`] for representation.
pub struct SizedRect<T, Unit> {
/// The origin of the rectangle.
pub origin: Point<T, Unit>,
/// The size of the rectangle.
pub size: Size<T, Unit>,
impl<T: Default, Unit> From<Size<T, Unit>> for SizedRect<T, Unit> {
Self::new(Point::default(), size)
impl<T, Unit> Debug for SizedRect<T, Unit>
f.debug_struct("SizedRect")
.field("origin", &self.origin)
.field("size", &self.size)
.finish()
impl<T, Unit> SizedRect<T, Unit> {
/// Returns a new rectangle using `origin` and `size`.
pub const fn new(origin: Point<T, Unit>, size: Size<T, Unit>) -> Self {
Self { origin, size }
impl<T, Unit> Copy for SizedRect<T, Unit> where T: Copy {}
impl<T, Unit> Clone for SizedRect<T, Unit>
Self {
origin: self.origin.clone(),
size: self.size.clone(),
impl<T, Unit> Eq for SizedRect<T, Unit> where T: Eq {}
impl<T, Unit> PartialEq for SizedRect<T, Unit>
T: PartialEq,
self.origin.eq(&other.origin) && self.size.eq(&other.size)
impl<T, Unit> SizedRect<T, Unit>
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<SizedRect<NewT, Unit>> {
Some(SizedRect::new(
self.origin.try_cast()?,
self.size.try_cast()?,
))
pub fn cast<NewT: NumCast + Copy>(&self) -> SizedRect<NewT, Unit> {
pub fn cast_unit<NewUnit>(&self) -> SizedRect<T, NewUnit> {
SizedRect::new(self.origin.cast_unit(), self.size.cast_unit())
impl<T, Unit> Default for SizedRect<T, Unit>
Self::new(Point::default(), Size::default())
impl<T, Unit> Round for SizedRect<T, Unit>
fn round(mut self) -> Self {
self.origin = self.origin.round();
self.size = self.size.round();
self
impl<T, Unit> Ceil for SizedRect<T, Unit>
fn ceil(mut self) -> Self {
self.origin = self.origin.ceil();
self.size = self.size.ceil();
impl<T, Unit> Floor for SizedRect<T, Unit>
fn floor(mut self) -> Self {
self.origin = self.origin.floor();
self.size = self.size.floor();
/// rounds the size out using `ceil`.
pub fn round_out(mut self) -> Self {
/// rounds the size in using `floor`.
pub fn round_in(mut self) -> Self {
impl<T, UnitA, UnitB> Mul<Scale<T, UnitA, UnitB>> for SizedRect<T, UnitA>
type Output = SizedRect<T, UnitB>;
SizedRect::new(self.origin * rhs, self.size * rhs)
impl<T, UnitA, UnitB> Div<crate::Scale<T, UnitA, UnitB>> for SizedRect<T, UnitB>
type Output = SizedRect<T, UnitA>;
SizedRect::new(self.origin / rhs, self.size / rhs)
impl<T, Unit> crate::Approx<T> for SizedRect<T, Unit>
T: approx::AbsDiffEq + Copy,
self.origin.approx_eq(&other.origin) && self.size.approx_eq(&other.size)
impl<T, Unit> approx::AbsDiffEq for SizedRect<T, Unit>
T: approx::AbsDiffEq<Epsilon = T> + Copy,
self.origin.abs_diff_eq(&other.origin, epsilon)
&& self.size.abs_diff_eq(&other.size, epsilon)
self.origin.abs_diff_ne(&other.origin, epsilon)
|| self.size.abs_diff_ne(&other.size, epsilon)
impl<T, Unit> approx::UlpsEq for SizedRect<T, Unit>
T: approx::UlpsEq<Epsilon = T> + Copy,
self.origin.ulps_eq(&other.origin, epsilon, max_ulps)
&& self.size.ulps_eq(&other.size, epsilon, max_ulps)
self.origin.ulps_ne(&other.origin, epsilon, max_ulps)
|| self.size.ulps_ne(&other.size, epsilon, max_ulps)
impl<T, Unit> approx::RelativeEq for SizedRect<T, Unit>
T: approx::RelativeEq<Epsilon = T> + Copy,
self.origin
.relative_eq(&other.origin, epsilon, max_relative)
&& self.size.relative_eq(&other.size, epsilon, max_relative)
.relative_ne(&other.origin, epsilon, max_relative)
|| self.size.relative_ne(&other.size, epsilon, max_relative)
impl<T> Displayable<T> for SizedRect<T, Scaled>
type Pixels = SizedRect<T, Pixels>;
type Points = SizedRect<T, Points>;
*self * scale.total
*self * scale.additional
impl<T> Displayable<T> for SizedRect<T, Points>
type Scaled = SizedRect<T, Scaled>;
*self * scale.dpi
*self / scale.additional
impl<T> Displayable<T> for SizedRect<T, Pixels>
*self / scale.dpi
*self / scale.total
/// A rectangle that uses two [`Point`]s for representation.
pub struct ExtentsRect<T, Unit> {
/// The non-origin point of the rectangle.
pub extent: Point<T, Unit>,
impl<T, Unit> Debug for ExtentsRect<T, Unit>
.field("extent", &self.extent)
impl<T, Unit> Copy for ExtentsRect<T, Unit> where T: Copy {}
impl<T, Unit> Clone for ExtentsRect<T, Unit>
extent: self.extent.clone(),
impl<T, Unit> ExtentsRect<T, Unit> {
/// Returns a new rectangle using `origin` and `extent`.
pub fn new(origin: Point<T, Unit>, extent: Point<T, Unit>) -> Self {
Self { origin, extent }
impl<T, Unit> ExtentsRect<T, Unit>
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<ExtentsRect<NewT, Unit>> {
Some(ExtentsRect::new(
self.extent.try_cast()?,
pub fn cast<NewT: NumCast + Copy>(&self) -> ExtentsRect<NewT, Unit> {
pub fn cast_unit<NewUnit>(&self) -> ExtentsRect<T, NewUnit> {
ExtentsRect::new(self.origin.cast_unit(), self.extent.cast_unit())
impl<T, Unit> Eq for ExtentsRect<T, Unit> where T: Eq {}
impl<T, Unit> PartialEq for ExtentsRect<T, Unit>
self.origin.eq(&other.origin) && self.extent.eq(&other.extent)
impl<T, Unit> Default for ExtentsRect<T, Unit>
Self::new(Point::default(), Point::default())
impl<T, Unit> Round for ExtentsRect<T, Unit>
self.extent = self.extent.round();
impl<T, Unit> Ceil for ExtentsRect<T, Unit>
self.extent = self.extent.ceil();
impl<T, Unit> Floor for ExtentsRect<T, Unit>
self.extent = self.extent.floor();
/// rounds the extent out using `ceil`.
/// rounds the extent in using `floor`.
impl<T, UnitA, UnitB> Mul<Scale<T, UnitA, UnitB>> for ExtentsRect<T, UnitA>
type Output = ExtentsRect<T, UnitB>;
ExtentsRect::new(self.origin * rhs, self.extent * rhs)
impl<T, UnitA, UnitB> Div<crate::Scale<T, UnitA, UnitB>> for ExtentsRect<T, UnitB>
type Output = ExtentsRect<T, UnitA>;
ExtentsRect::new(self.origin / rhs, self.extent / rhs)
impl<T, Unit> crate::Approx<T> for ExtentsRect<T, Unit>
self.origin.approx_eq(&other.origin) && self.extent.approx_eq(&other.extent)
impl<T, Unit> approx::AbsDiffEq for ExtentsRect<T, Unit>
&& self.extent.abs_diff_eq(&other.extent, epsilon)
|| self.extent.abs_diff_ne(&other.extent, epsilon)
impl<T, Unit> approx::UlpsEq for ExtentsRect<T, Unit>
&& self.extent.ulps_eq(&other.extent, epsilon, max_ulps)
|| self.extent.ulps_ne(&other.extent, epsilon, max_ulps)
impl<T, Unit> approx::RelativeEq for ExtentsRect<T, Unit>
&& self
.extent
.relative_eq(&other.extent, epsilon, max_relative)
|| self
.relative_ne(&other.extent, epsilon, max_relative)
impl<T> Displayable<T> for ExtentsRect<T, Scaled>
type Pixels = ExtentsRect<T, Pixels>;
type Points = ExtentsRect<T, Points>;
impl<T> Displayable<T> for ExtentsRect<T, Points>
type Scaled = ExtentsRect<T, Scaled>;
impl<T> Displayable<T> for ExtentsRect<T, Pixels>
/// Functionalitiy that all rectangle types implement
pub trait Rectlike<T, Unit>: Sized
/// Returns this rectangle as a `Rect`. The rectangle's underlying data will
/// be unchanged by this operation.
fn as_rect(&self) -> Rect<T, Unit>;
/// Returns this rectangle converted to an [`ExtentsRect`].
fn as_extents(&self) -> ExtentsRect<T, Unit>;
/// Returns this rectangle converted to a [`SizedRect`].
fn as_sized(&self) -> SizedRect<T, Unit>;
/// Checks to see if this rect is empty. If it is, None is returned. If it
/// isn't, the rect is returned unmodified.
fn to_non_empty(self) -> Option<Self> {
if self.is_empty() {
None
} else {
Some(self)
/// Returns true if the rect doesn't have a positive width and height.
fn is_empty(&self) -> bool {
let zero = T::zero();
!(self.width().get() > zero && self.height().get() > zero)
/// Returns the area contained by this rectangle.
fn area(&self) -> Figure<T, Unit> {
self.width() * self.height()
/// Returns the width of the rectangle.
fn width(&self) -> Figure<T, Unit>;
/// Returns the height of the rectangle.
fn height(&self) -> Figure<T, Unit>;
/// Returns the size of the rectangle.
fn size(&self) -> Size<T, Unit> {
Size::from_figures(self.width(), self.height())
/// Returns the origin of the rectangle.
fn origin(&self) -> Point<T, Unit>;
/// Returns the center of the rectangle.
fn center(&self) -> Point<T, Unit> {
self.origin() + self.size() / (T::one() + T::one())
/// Returns true if `point` is within this rectangle.
fn contains(&self, point: Point<T, Unit>) -> bool {
let extents = self.as_extents();
extents.origin.x <= point.x
&& extents.origin.y <= point.y
&& extents.extent.x >= point.x
&& extents.extent.y >= point.y
/// Moves this rectangle by the vector provided.
fn translate<V: Into<Vector<T, Unit>>>(&self, by: V) -> Self;
/// Increases the size of this rectangle by the vector provided. The rectangle will grow around its center.
fn inflate<V: Into<Vector<T, Unit>>>(&self, by: V) -> Self;
/// Returns the intersecting area between the two rectangles. If the
/// rectangles do not intersect, None is returned.
fn intersection<R: Rectlike<T, Unit>>(&self, other: &R) -> Option<ExtentsRect<T, Unit>> {
let r1 = self.as_extents();
let r2 = other.as_extents();
ExtentsRect::new(r1.origin.max(&r2.origin), r1.extent.min(&r2.extent)).to_non_empty()
/// Returns the union of the two rectangles. If both rectangles aren't
/// empty, the smallest rectangle that both rectangles can fit into will be
/// returned. If either rectangle is empty, the other rectangle is returned
/// unmodified.
fn union<R: Rectlike<T, Unit>>(&self, other: &R) -> Option<ExtentsRect<T, Unit>> {
match (
self.as_extents().to_non_empty(),
other.as_extents().to_non_empty(),
) {
(Some(r1), Some(r2)) => {
ExtentsRect::new(r1.origin.min(&r2.origin), r1.extent.max(&r2.extent))
.to_non_empty()
(Some(r), None) | (None, Some(r)) => Some(r),
(None, None) => None,
impl<T, Unit> Rectlike<T, Unit> for Rect<T, Unit>
fn as_rect(&self) -> Rect<T, Unit> {
fn as_extents(&self) -> ExtentsRect<T, Unit> {
Rect::Sized(sized) => sized.as_extents(),
Rect::Extents(extents) => extents.as_extents(),
fn as_sized(&self) -> SizedRect<T, Unit> {
Rect::Sized(sized) => sized.as_sized(),
Rect::Extents(extents) => extents.as_sized(),
fn width(&self) -> Figure<T, Unit> {
Rect::Sized(sized) => sized.width(),
Rect::Extents(extents) => extents.width(),
fn height(&self) -> Figure<T, Unit> {
Rect::Sized(sized) => sized.height(),
Rect::Extents(extents) => extents.height(),
fn origin(&self) -> Point<T, Unit> {
Rect::Sized(sized) => sized.origin(),
Rect::Extents(extents) => extents.origin(),
fn translate<V: Into<Vector<T, Unit>>>(&self, by: V) -> Self {
Rect::Sized(sized) => Rect::Sized(sized.translate(by)),
Rect::Extents(extents) => Rect::Extents(extents.translate(by)),
fn inflate<V: Into<Vector<T, Unit>>>(&self, by: V) -> Self {
Rect::Sized(sized) => Rect::Sized(sized.inflate(by)),
Rect::Extents(extents) => Rect::Extents(extents.inflate(by)),
impl<T, Unit> Rectlike<T, Unit> for ExtentsRect<T, Unit>
Rect::Extents(*self)
fn as_extents(&self) -> Self {
SizedRect::new(
self.origin,
(self.extent.to_vector() - self.origin.to_vector()).to_size(),
)
self.extent.x() - self.origin.x()
self.extent.y() - self.origin.y()
let by = by.into();
origin: self.origin + by,
extent: self.extent + by,
let half = by.into() / (T::one() + T::one());
origin: self.origin - half,
extent: self.extent + half,
impl<T, Unit> Rectlike<T, Unit> for SizedRect<T, Unit>
Rect::Sized(*self)
ExtentsRect::new(self.origin, self.origin + self.size)
fn as_sized(&self) -> Self {
self.size.width()
self.size.height()
size: self.size,
let half = by / (T::one() + T::one());
size: self.size + by,
#[test]
fn intersection_tests() {
let a = SizedRect::<u32, ()>::new(Point::new(10, 20), Size::new(90, 80));
let b = SizedRect::new(Point::new(50, 50), Size::new(50, 50));
assert_eq!(
a.intersection(&b),
Some(ExtentsRect::new(Point::new(50, 50), Point::new(100, 100)))
);
fn contains_test() {
let a = SizedRect::<u32, ()>::new(Point::new(10, 20), Size::new(30, 40));
assert!(a.contains(Point::new(10, 20)));
assert!(a.contains(Point::new(11, 20)));
assert!(a.contains(Point::new(10, 21)));
assert!(a.contains(Point::new(40, 60)));
assert!(a.contains(Point::new(39, 60)));
assert!(a.contains(Point::new(40, 59)));
assert!(!a.contains(Point::new(9, 20)));
assert!(!a.contains(Point::new(10, 19)));
assert!(!a.contains(Point::new(41, 20)));
assert!(!a.contains(Point::new(40, 19)));
assert!(!a.contains(Point::new(9, 60)));
assert!(!a.contains(Point::new(10, 61)));
assert!(!a.contains(Point::new(41, 60)));
assert!(!a.contains(Point::new(40, 61)));
fn inflation_tests() {
let a = SizedRect::<u32, ()>::new(Point::new(2, 3), Size::new(4, 5));
let inflated = a.inflate(Vector::new(2, 2));
assert_eq!(inflated, SizedRect::new(Point::new(1, 2), Size::new(6, 7)));
a.as_extents().inflate(Vector::new(2, 2)),
inflated.as_extents()