path_traits/segment.rs
1//! Working with multi-segment paths.
2//!
3//! This module provides:
4//!
5//! - [`PathSegment`] - a marker for a primitive curve that is not further subdivided
6//! - [`SegmentedPath`] - a path composed of multiple segments, offering
7//! enumeration, indexing, and arc-length-to-segment location
8
9use crate::Path;
10
11/// Marker for a primitive curve that cannot be further subdivided.
12///
13/// Types implementing this trait represent atomic path building blocks (e.g. a
14/// line segment, a Bézier curve). They behave exactly like a [`Path`] but signal
15/// to [`SegmentedPath`] consumers that no further subdivision is expected.
16pub trait PathSegment: Path {}
17
18/// A path made up of multiple [`PathSegment`]s.
19///
20/// Provides methods to enumerate segments, access them by index, and map a
21/// global arc-length parameter to a `(segment_index, local_s)` pair.
22pub trait SegmentedPath: Path {
23 /// The type of individual segments making up this path.
24 type Segment: PathSegment<Scalar = Self::Scalar, Point = Self::Point, Error = Self::Error>;
25
26 /// Number of segments in this path.
27 fn segment_count(&self) -> usize;
28
29 /// Iterator over all segments.
30 fn segments(&self) -> impl Iterator<Item = &Self::Segment> + '_;
31
32 /// Get the segment at index `i`, or `None` if out of bounds.
33 fn segment(&self, i: usize) -> Option<&Self::Segment> {
34 self.segments().nth(i)
35 }
36
37 /// Map global arc-length `s` to `(segment_index, local_s)`.
38 ///
39 /// Returns the index of the segment containing `s` and the local arc-length
40 /// within that segment. Errors when `s` is outside the path's domain.
41 fn locate(&self, s: Self::Scalar) -> Result<(usize, Self::Scalar), Self::Error>;
42}