path_traits/transform/mod.rs
1//! Path composition and transformation.
2//!
3//! Build new paths from existing ones without modifying the original data:
4//!
5//! - [`Reverse`] - traverse a path backwards
6//! - [`Concat`] - join two paths end-to-end
7//! - [`Offset`] - displace a path by a constant distance
8//!
9//! The [`PathExt`] extension trait provides ergonomic `.reverse()`, `.concat()`,
10//! and `.offset()` methods on any type implementing [`Path`](crate::Path).
11
12mod concat;
13mod offset;
14mod reverse;
15
16pub use concat::Concat;
17pub use offset::Offset;
18pub use reverse::Reverse;
19
20use crate::{Heading, Path, Tangent};
21
22/// Ergonomic methods for path composition and transformation.
23///
24/// Provides `.reverse()`, `.concat()`, and `.offset()` methods on any
25/// type implementing [`Path`] (with additional bounds where required).
26pub trait PathExt: Path + Sized {
27 /// Reverse the path direction.
28 fn reverse(self) -> Reverse<Self>;
29
30 /// Concatenate this path with another, compatible path.
31 fn concat<Q>(self, other: Q) -> Concat<Self, Q>
32 where
33 Q: Path<Scalar = Self::Scalar, Point = Self::Point, Error = Self::Error>;
34
35 /// Offset the path by a distance `d`. Requires tangent and heading support.
36 fn offset(self, d: Self::Scalar) -> Offset<Self, Self::Scalar>
37 where
38 Self: Tangent + Heading;
39}
40
41impl<P: Path + Sized> PathExt for P {
42 fn reverse(self) -> Reverse<Self> {
43 Reverse::new(self)
44 }
45
46 fn concat<Q>(self, other: Q) -> Concat<Self, Q>
47 where
48 Q: Path<Scalar = Self::Scalar, Point = Self::Point, Error = Self::Error>,
49 {
50 Concat::new(self, other)
51 }
52
53 fn offset(self, d: Self::Scalar) -> Offset<Self, Self::Scalar>
54 where
55 Self: Tangent + Heading,
56 {
57 Offset::new(self, d)
58 }
59}