motion_core/path2d/
builder.rs1use super::Path2D;
4use crate::{Point, ValidationError, Vector2};
5
6#[derive(Clone, Debug, Default)]
22#[must_use = "a path builder does nothing until `build` is called"]
23pub struct PathBuilder {
24 path: Path2D,
25 error: Option<ValidationError>,
26}
27
28impl PathBuilder {
29 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn move_to(self, point: Point) -> Self {
36 self.step(|path| path.try_move_to(point))
37 }
38
39 pub fn line_to(self, point: Point) -> Self {
41 self.step(|path| path.try_line_to(point))
42 }
43
44 pub fn quadratic_to(self, control: Point, end: Point) -> Self {
46 self.step(|path| path.try_quadratic_to(control, end))
47 }
48
49 pub fn cubic_to(self, first: Point, second: Point, end: Point) -> Self {
51 self.step(|path| path.try_cubic_to(first, second, end))
52 }
53
54 pub fn arc_to(self, center: Point, radii: Vector2, start_angle: f64, sweep_angle: f64) -> Self {
56 self.step(|path| path.try_arc_to(center, radii, start_angle, sweep_angle))
57 }
58
59 pub fn close(self) -> Self {
61 self.step(Path2D::try_close)
62 }
63
64 pub fn build(self) -> Result<Path2D, ValidationError> {
66 match self.error {
67 Some(error) => Err(error),
68 None => Ok(self.path),
69 }
70 }
71
72 fn step(mut self, apply: impl FnOnce(&mut Path2D) -> Result<(), ValidationError>) -> Self {
73 if self.error.is_none()
74 && let Err(error) = apply(&mut self.path)
75 {
76 self.error = Some(error);
77 }
78 self
79 }
80}