Skip to main content

geometry_model/
pointing_segment.rs

1//! Borrowing segment model whose indexed access forwards to two points.
2//!
3//! Mirrors `boost::geometry::model::pointing_segment<Point>` from
4//! `geometries/pointing_segment.hpp:39-72` and its indexed-access
5//! specializations at lines 91-137.
6
7use geometry_tag::SegmentTag;
8use geometry_trait::{Geometry, IndexedAccess, PointMut, Segment};
9
10/// A segment borrowing two mutable endpoints instead of storing copies.
11///
12/// Mirrors `model::pointing_segment` from
13/// `geometries/pointing_segment.hpp:39-72`. Boost stores nullable raw
14/// pointers because its segment iterator requires default construction. Rust
15/// represents only the valid, non-null state and uses the borrow checker to
16/// prevent the endpoints from outliving their source.
17#[derive(Debug)]
18pub struct PointingSegment<'a, P: PointMut> {
19    start: &'a mut P,
20    end: &'a mut P,
21}
22
23impl<'a, P: PointMut> PointingSegment<'a, P> {
24    /// Borrow two endpoints as a segment.
25    ///
26    /// Mirrors `pointing_segment(p1, p2)` from
27    /// `geometries/pointing_segment.hpp:67-71` while eliminating the C++
28    /// model's nullable default state.
29    #[inline]
30    #[must_use]
31    pub const fn new(start: &'a mut P, end: &'a mut P) -> Self {
32        Self { start, end }
33    }
34
35    /// Borrow the first endpoint.
36    #[inline]
37    #[must_use]
38    pub const fn start(&self) -> &P {
39        self.start
40    }
41
42    /// Borrow the second endpoint.
43    #[inline]
44    #[must_use]
45    pub const fn end(&self) -> &P {
46        self.end
47    }
48}
49
50impl<P: PointMut> Geometry for PointingSegment<'_, P> {
51    type Kind = SegmentTag;
52    type Point = P;
53}
54
55impl<P: PointMut> IndexedAccess for PointingSegment<'_, P> {
56    #[inline]
57    fn get_indexed<const I: usize, const D: usize>(&self) -> P::Scalar {
58        if I == 0 {
59            self.start.get::<D>()
60        } else {
61            self.end.get::<D>()
62        }
63    }
64
65    #[inline]
66    fn set_indexed<const I: usize, const D: usize>(&mut self, value: P::Scalar) {
67        if I == 0 {
68            self.start.set::<D>(value);
69        } else {
70            self.end.set::<D>(value);
71        }
72    }
73}
74
75impl<P: PointMut> Segment for PointingSegment<'_, P> {}