geometry_model/
pointing_segment.rs1use geometry_tag::SegmentTag;
8use geometry_trait::{Geometry, IndexedAccess, PointMut, Segment};
9
10#[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 #[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 #[inline]
37 #[must_use]
38 pub const fn start(&self) -> &P {
39 self.start
40 }
41
42 #[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 match I {
59 0 => self.start.get::<D>(),
60 1 => self.end.get::<D>(),
61 _ => panic!("PointingSegment::get_indexed: endpoint index {I} is out of range"),
62 }
63 }
64
65 #[inline]
66 fn set_indexed<const I: usize, const D: usize>(&mut self, value: P::Scalar) {
67 match I {
68 0 => self.start.set::<D>(value),
69 1 => self.end.set::<D>(value),
70 _ => panic!("PointingSegment::set_indexed: endpoint index {I} is out of range"),
71 }
72 }
73}
74
75impl<P: PointMut> Segment for PointingSegment<'_, P> {}
76
77#[cfg(test)]
78mod tests {
79 use geometry_cs::Cartesian;
83 use geometry_trait::IndexedAccess as _;
84
85 use super::PointingSegment;
86 use crate::Point2D;
87
88 type P = Point2D<f64, Cartesian>;
89
90 #[test]
91 #[should_panic(expected = "endpoint index 2 is out of range")]
92 fn reading_a_third_endpoint_panics_instead_of_aliasing_the_end() {
93 let mut start = P::new(1.0, 2.0);
94 let mut end = P::new(3.0, 4.0);
95 let segment = PointingSegment::new(&mut start, &mut end);
96 let _ = segment.get_indexed::<2, 0>();
97 }
98
99 #[test]
100 #[should_panic(expected = "endpoint index 2 is out of range")]
101 fn writing_a_third_endpoint_panics_instead_of_aliasing_the_end() {
102 let mut start = P::new(1.0, 2.0);
103 let mut end = P::new(3.0, 4.0);
104 let mut segment = PointingSegment::new(&mut start, &mut end);
105 segment.set_indexed::<2, 0>(9.0);
106 }
107}