use crate::intersects::{CartesianIntersects, IntersectsStrategy};
pub trait DisjointStrategy<A, B> {
fn disjoint(&self, a: &A, b: &B) -> bool;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct CartesianDisjoint;
impl<A, B> DisjointStrategy<A, B> for CartesianDisjoint
where
CartesianIntersects: IntersectsStrategy<A, B>,
{
#[inline]
fn disjoint(&self, a: &A, b: &B) -> bool {
!CartesianIntersects.intersects(a, b)
}
}
#[cfg(test)]
mod tests {
use super::{CartesianDisjoint, DisjointStrategy};
use geometry_cs::Cartesian;
use geometry_model::{Linestring, Point2D, linestring};
type P = Point2D<f64, Cartesian>;
type LS = Linestring<P>;
#[test]
fn linestrings_disjoint_when_apart() {
let a: LS = linestring![(0.0, 0.0), (2.0, 0.0)];
let b: LS = linestring![(10.0, 10.0), (11.0, 11.0)];
assert!(CartesianDisjoint.disjoint(&a, &b));
}
#[test]
fn linestrings_not_disjoint_when_crossing() {
let a: LS = linestring![(0.0, 0.0), (2.0, 0.0)];
let b: LS = linestring![(1.0, -1.0), (1.0, 1.0)];
assert!(!CartesianDisjoint.disjoint(&a, &b));
}
fn _accepts_readonly_point<A, B, S>(s: &S, a: &A, b: &B) -> bool
where
A: geometry_trait::Point,
B: geometry_trait::Point,
S: DisjointStrategy<A, B>,
{
s.disjoint(a, b)
}
#[test]
#[allow(
clippy::used_underscore_items,
reason = "the test exists to run the compile-time witness's body"
)]
fn readonly_point_witness_computes_disjointness() {
assert!(_accepts_readonly_point(
&CartesianDisjoint,
&P::new(0.0, 0.0),
&P::new(1.0, 1.0)
));
assert!(!_accepts_readonly_point(
&CartesianDisjoint,
&P::new(1.0, 1.0),
&P::new(1.0, 1.0)
));
}
}