1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
//! Traits for checking whether a shape contains another shape.
use serde::{Deserialize, Serialize};
/// Ways in which an inner shape can be contained within an enclosing shape.
#[derive(
Debug, Default, Clone, Copy, Serialize, Deserialize, Hash, PartialEq, Eq, Ord, PartialOrd,
)]
pub enum Containment {
/// The enclosing shape does not contain any part of the inner shape.
#[default]
None,
/// The shape is partially contained in the enclosing shape.
Partial,
/// The shape is fully contained in the enclosing shape.
Full,
}
/// Provides information on whether a shape contains another shape.
pub trait Contains<T> {
/// Returns a [`Containment`] indicating how `other` is enclosed within this shape.
///
/// * If `other` is entirely contained, returns [`Containment::Full`].
/// * If `other` is only partially contained, returns [`Containment::Partial`].
/// * If no part of `other` lies within this shape, returns [`Containment::None`].
fn contains(&self, other: &T) -> Containment;
/// Returns true if `other` is fully enclosed in this shape.
#[inline]
fn encloses(&self, other: &T) -> bool {
self.contains(other).is_full()
}
/// Returns true if `other` is fully or partially enclosed in this shape.
#[inline]
fn partially_intersects(&self, other: &T) -> bool {
self.contains(other).intersects()
}
}
impl Containment {
/// Returns true when fully contained.
#[inline]
pub fn is_full(&self) -> bool {
matches!(self, Self::Full)
}
/// Returns true if there is **at least** partial containment.
#[inline]
pub fn intersects(&self) -> bool {
matches!(self, Self::Full | Self::Partial)
}
/// Returns true if there is **only** partial containment.
#[inline]
pub fn only_partially_intersects(&self) -> bool {
matches!(self, Self::Partial)
}
/// Returns true if there is no containment.
#[inline]
pub fn is_none(&self) -> bool {
matches!(self, Self::None)
}
}