path-traits 0.1.0

Tower-like generic traits for parametric paths, segments, and geometric queries
Documentation
//! Working with multi-segment paths.
//!
//! This module provides:
//!
//! - [`PathSegment`] - a marker for a primitive curve that is not further subdivided
//! - [`SegmentedPath`] - a path composed of multiple segments, offering
//!   enumeration, indexing, and arc-length-to-segment location

use crate::Path;

/// Marker for a primitive curve that cannot be further subdivided.
///
/// Types implementing this trait represent atomic path building blocks (e.g. a
/// line segment, a Bézier curve). They behave exactly like a [`Path`] but signal
/// to [`SegmentedPath`] consumers that no further subdivision is expected.
pub trait PathSegment: Path {}

/// A path made up of multiple [`PathSegment`]s.
///
/// Provides methods to enumerate segments, access them by index, and map a
/// global arc-length parameter to a `(segment_index, local_s)` pair.
pub trait SegmentedPath: Path {
    /// The type of individual segments making up this path.
    type Segment: PathSegment<Scalar = Self::Scalar, Point = Self::Point, Error = Self::Error>;

    /// Number of segments in this path.
    fn segment_count(&self) -> usize;

    /// Iterator over all segments.
    fn segments(&self) -> impl Iterator<Item = &Self::Segment> + '_;

    /// Get the segment at index `i`, or `None` if out of bounds.
    fn segment(&self, i: usize) -> Option<&Self::Segment> {
        self.segments().nth(i)
    }

    /// Map global arc-length `s` to `(segment_index, local_s)`.
    ///
    /// Returns the index of the segment containing `s` and the local arc-length
    /// within that segment. Errors when `s` is outside the path's domain.
    fn locate(&self, s: Self::Scalar) -> Result<(usize, Self::Scalar), Self::Error>;
}