use super::Path2D;
use crate::{Point, ValidationError, Vector2};
#[derive(Clone, Debug, Default)]
#[must_use = "a path builder does nothing until `build` is called"]
pub struct PathBuilder {
path: Path2D,
error: Option<ValidationError>,
}
impl PathBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn move_to(self, point: Point) -> Self {
self.step(|path| path.try_move_to(point))
}
pub fn line_to(self, point: Point) -> Self {
self.step(|path| path.try_line_to(point))
}
pub fn quadratic_to(self, control: Point, end: Point) -> Self {
self.step(|path| path.try_quadratic_to(control, end))
}
pub fn cubic_to(self, first: Point, second: Point, end: Point) -> Self {
self.step(|path| path.try_cubic_to(first, second, end))
}
pub fn arc_to(self, center: Point, radii: Vector2, start_angle: f64, sweep_angle: f64) -> Self {
self.step(|path| path.try_arc_to(center, radii, start_angle, sweep_angle))
}
pub fn close(self) -> Self {
self.step(Path2D::try_close)
}
pub fn build(self) -> Result<Path2D, ValidationError> {
match self.error {
Some(error) => Err(error),
None => Ok(self.path),
}
}
fn step(mut self, apply: impl FnOnce(&mut Path2D) -> Result<(), ValidationError>) -> Self {
if self.error.is_none()
&& let Err(error) = apply(&mut self.path)
{
self.error = Some(error);
}
self
}
}