From 09cabd6520c3d41995d18bd279abb3fb81fb5950 Mon Sep 17 00:00:00 2001 From: matt rice Date: Sat, 27 Jan 2024 09:26:01 -0800 Subject: [PATCH 1/8] Initial implementation of a StaticShape type --- src/lib.rs | 2 + src/static_shape.rs | 221 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 src/static_shape.rs diff --git a/src/lib.rs b/src/lib.rs index b5088b4e..a9d7570e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,6 +108,7 @@ mod rounded_rect_radii; mod shape; pub mod simplify; mod size; +mod static_shape; mod stroke; #[cfg(feature = "std")] mod svg; @@ -132,6 +133,7 @@ pub use crate::rounded_rect::*; pub use crate::rounded_rect_radii::*; pub use crate::shape::*; pub use crate::size::*; +pub use crate::static_shape::*; pub use crate::stroke::*; #[cfg(feature = "std")] pub use crate::svg::*; diff --git a/src/static_shape.rs b/src/static_shape.rs new file mode 100644 index 00000000..cb04fc2c --- /dev/null +++ b/src/static_shape.rs @@ -0,0 +1,221 @@ +use crate::{Point, Rect, Shape}; +use alloc::boxed::Box; + +mod _never_shape { + use super::*; + use crate::PathEl; + /// An uninhabited type that implements shape. + #[derive(Debug, Clone, Copy, PartialEq)] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + pub enum NeverShape {} + impl Shape for NeverShape { + type PathElementsIter<'a> = core::iter::Empty; + fn path_elements(&self, _: f64) -> Self::PathElementsIter<'_> { + unreachable!() + } + fn area(&self) -> f64 { + unreachable!() + } + fn perimeter(&self, _: f64) -> f64 { + unreachable!() + } + fn winding(&self, _: Point) -> i32 { + unreachable!() + } + fn bounding_box(&self) -> Rect { + unreachable!() + } + } +} + +/// Because the `Shape` trait is not dyn safe, it can be difficult to store +/// Collections of `Shape` items in hetereogenuous collections. +/// +/// It allows an external `Shape` impl to be provided as an extension point +/// for shape impls provided by external crates. This defaults to an +/// uninhabited type. +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[non_exhaustive] +pub enum StaticShape +where + External: Shape, +{ + /// Corresponds to a `PathSeg` + PathSeg(crate::PathSeg), + /// Corresponds to an `Arc` + Arc(crate::Arc), + /// Corresponds to a `BezPath` + BezPath(crate::BezPath), + /// Corresponds to a `Circle` + Circle(crate::Circle), + /// Corresponds to a `CircleSegment` + CircleSegment(crate::CircleSegment), + /// Corresponds to a `CubicBez` + CubicBez(crate::CubicBez), + /// Corresponds to an `Ellipse` + Ellipse(crate::Ellipse), + /// Corresponds to a `Line` + Line(crate::Line), + /// Corresponds to a `QuadBez` + QuadBez(crate::QuadBez), + /// Corresponds to a `Rect` + Rect(crate::Rect), + /// Corresponds to a `RoundedRect` + RoundedRect(crate::RoundedRect), + /// A type implementing shape that may be defined by an external crate. + External(External), +} + +macro_rules! from_shape { + ($it: ident) => { + impl From for StaticShape { + fn from(it: crate::$it) -> Self { + Self::$it(it) + } + } + }; +} + +from_shape!(PathSeg); +from_shape!(Arc); +from_shape!(BezPath); +from_shape!(Circle); +from_shape!(CircleSegment); +from_shape!(CubicBez); +from_shape!(Ellipse); +from_shape!(Line); +from_shape!(QuadBez); +from_shape!(Rect); +from_shape!(RoundedRect); + +impl StaticShape { + /// Builds a static shape from an external shape implementation. + /// + /// For a kurbo provided shape implementation, you would normally use the `from` impl instead. + pub fn from_external_shape(shape: External) -> StaticShape + where + External: Shape, + { + StaticShape::External(shape) + } +} + +impl Shape for StaticShape +where + External: Shape, +{ + type PathElementsIter<'iter> = Box + 'iter> where External: 'iter; + fn path_elements(&self, tol: f64) -> Box + '_> { + use StaticShape as S; + match self { + S::PathSeg(it) => Box::new(it.path_elements(tol)), + S::Arc(it) => Box::new(it.path_elements(tol)), + S::BezPath(it) => Box::new(it.path_elements(tol)), + S::Circle(it) => Box::new(it.path_elements(tol)), + S::CircleSegment(it) => Box::new(it.path_elements(tol)), + S::CubicBez(it) => Box::new(it.path_elements(tol)), + S::Ellipse(it) => Box::new(it.path_elements(tol)), + S::Line(it) => Box::new(it.path_elements(tol)), + S::QuadBez(it) => Box::new(it.path_elements(tol)), + S::Rect(it) => Box::new(it.path_elements(tol)), + S::RoundedRect(it) => Box::new(it.path_elements(tol)), + S::External(it) => Box::new(it.path_elements(tol)), + } + } + + fn perimeter(&self, acc: f64) -> f64 { + use StaticShape as S; + match self { + S::PathSeg(it) => it.perimeter(acc), + S::Arc(it) => it.perimeter(acc), + S::BezPath(it) => it.perimeter(acc), + S::Circle(it) => it.perimeter(acc), + S::CircleSegment(it) => it.perimeter(acc), + S::CubicBez(it) => it.perimeter(acc), + S::Ellipse(it) => it.perimeter(acc), + S::Line(it) => it.perimeter(acc), + S::QuadBez(it) => it.perimeter(acc), + S::Rect(it) => it.perimeter(acc), + S::RoundedRect(it) => it.perimeter(acc), + S::External(it) => it.perimeter(acc), + } + } + + fn area(&self) -> f64 { + use StaticShape as S; + match self { + S::PathSeg(it) => it.area(), + S::Arc(it) => it.area(), + S::BezPath(it) => it.area(), + S::Circle(it) => it.area(), + S::CircleSegment(it) => it.area(), + S::CubicBez(it) => it.area(), + S::Ellipse(it) => it.area(), + S::Line(it) => it.area(), + S::QuadBez(it) => it.area(), + S::Rect(it) => it.area(), + S::RoundedRect(it) => it.area(), + S::External(it) => it.area(), + } + } + + fn winding(&self, pt: Point) -> i32 { + use StaticShape as S; + match self { + S::PathSeg(it) => it.winding(pt), + S::Arc(it) => it.winding(pt), + S::BezPath(it) => it.winding(pt), + S::Circle(it) => it.winding(pt), + S::CircleSegment(it) => it.winding(pt), + S::CubicBez(it) => it.winding(pt), + S::Ellipse(it) => it.winding(pt), + S::Line(it) => it.winding(pt), + S::QuadBez(it) => it.winding(pt), + S::Rect(it) => it.winding(pt), + S::RoundedRect(it) => it.winding(pt), + S::External(it) => it.winding(pt), + } + } + + fn bounding_box(&self) -> Rect { + use StaticShape as S; + match self { + S::PathSeg(it) => it.bounding_box(), + S::Arc(it) => it.bounding_box(), + S::BezPath(it) => it.bounding_box(), + S::Circle(it) => it.bounding_box(), + + S::CircleSegment(it) => it.bounding_box(), + S::CubicBez(it) => it.bounding_box(), + S::Ellipse(it) => it.bounding_box(), + S::Line(it) => it.bounding_box(), + S::QuadBez(it) => it.bounding_box(), + S::Rect(it) => it.bounding_box(), + S::RoundedRect(it) => it.bounding_box(), + S::External(it) => it.bounding_box(), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_collection() { + let r = crate::Rect::from_origin_size((0.0, 0.0), (1.0, 1.0)); + let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); + let shapes: Vec = vec![r.into(), l.into()]; + assert_eq!(shapes, vec![StaticShape::Rect(r), StaticShape::Line(l),]) + } + #[test] + fn test_external() { + let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); + assert_eq!( + StaticShape::from_external_shape(l), + StaticShape::External(l) + ); + } +} From dff28648388e58284b30108508d7bcda0afd7455 Mon Sep 17 00:00:00 2001 From: matt rice Date: Fri, 15 Mar 2024 08:20:02 -0700 Subject: [PATCH 2/8] Appease clippy --- src/static_shape.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static_shape.rs b/src/static_shape.rs index cb04fc2c..343b2196 100644 --- a/src/static_shape.rs +++ b/src/static_shape.rs @@ -208,7 +208,7 @@ mod test { let r = crate::Rect::from_origin_size((0.0, 0.0), (1.0, 1.0)); let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); let shapes: Vec = vec![r.into(), l.into()]; - assert_eq!(shapes, vec![StaticShape::Rect(r), StaticShape::Line(l),]) + assert_eq!(shapes, vec![StaticShape::Rect(r), StaticShape::Line(l),]); } #[test] fn test_external() { From 14bd56cad08f68503ec48f7b3065df19f4f9bc4b Mon Sep 17 00:00:00 2001 From: matt rice Date: Fri, 29 Mar 2024 04:36:30 -0700 Subject: [PATCH 3/8] Add copyright notice --- src/static_shape.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/static_shape.rs b/src/static_shape.rs index 343b2196..1995d446 100644 --- a/src/static_shape.rs +++ b/src/static_shape.rs @@ -1,3 +1,6 @@ +// Copyright 2024 the Kurbo Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use crate::{Point, Rect, Shape}; use alloc::boxed::Box; From bc9d1ce82290dfef409b9d2f8e54c7aadaced88f Mon Sep 17 00:00:00 2001 From: matt rice Date: Wed, 29 May 2024 12:51:19 -0700 Subject: [PATCH 4/8] macroize match statements as suggested --- src/static_shape.rs | 101 +++++++++++--------------------------------- 1 file changed, 25 insertions(+), 76 deletions(-) diff --git a/src/static_shape.rs b/src/static_shape.rs index 1995d446..fd97edb4 100644 --- a/src/static_shape.rs +++ b/src/static_shape.rs @@ -106,100 +106,49 @@ impl StaticShape { } } +macro_rules! match_shape { + ($x:ident, $it:ident, $e: expr) => {{ + use StaticShape as S; + match $x { + S::PathSeg($it) => $e, + S::Arc($it) => $e, + S::BezPath($it) => $e, + S::Circle($it) => $e, + S::CircleSegment($it) => $e, + S::CubicBez($it) => $e, + S::Ellipse($it) => $e, + S::Line($it) => $e, + S::QuadBez($it) => $e, + S::Rect($it) => $e, + S::RoundedRect($it) => $e, + S::External($it) => $e, + } + }} +} + impl Shape for StaticShape where External: Shape, { type PathElementsIter<'iter> = Box + 'iter> where External: 'iter; fn path_elements(&self, tol: f64) -> Box + '_> { - use StaticShape as S; - match self { - S::PathSeg(it) => Box::new(it.path_elements(tol)), - S::Arc(it) => Box::new(it.path_elements(tol)), - S::BezPath(it) => Box::new(it.path_elements(tol)), - S::Circle(it) => Box::new(it.path_elements(tol)), - S::CircleSegment(it) => Box::new(it.path_elements(tol)), - S::CubicBez(it) => Box::new(it.path_elements(tol)), - S::Ellipse(it) => Box::new(it.path_elements(tol)), - S::Line(it) => Box::new(it.path_elements(tol)), - S::QuadBez(it) => Box::new(it.path_elements(tol)), - S::Rect(it) => Box::new(it.path_elements(tol)), - S::RoundedRect(it) => Box::new(it.path_elements(tol)), - S::External(it) => Box::new(it.path_elements(tol)), - } + match_shape!(self, it, Box::new(it.path_elements(tol))) } fn perimeter(&self, acc: f64) -> f64 { - use StaticShape as S; - match self { - S::PathSeg(it) => it.perimeter(acc), - S::Arc(it) => it.perimeter(acc), - S::BezPath(it) => it.perimeter(acc), - S::Circle(it) => it.perimeter(acc), - S::CircleSegment(it) => it.perimeter(acc), - S::CubicBez(it) => it.perimeter(acc), - S::Ellipse(it) => it.perimeter(acc), - S::Line(it) => it.perimeter(acc), - S::QuadBez(it) => it.perimeter(acc), - S::Rect(it) => it.perimeter(acc), - S::RoundedRect(it) => it.perimeter(acc), - S::External(it) => it.perimeter(acc), - } + match_shape!(self, it, it.perimeter(acc)) } fn area(&self) -> f64 { - use StaticShape as S; - match self { - S::PathSeg(it) => it.area(), - S::Arc(it) => it.area(), - S::BezPath(it) => it.area(), - S::Circle(it) => it.area(), - S::CircleSegment(it) => it.area(), - S::CubicBez(it) => it.area(), - S::Ellipse(it) => it.area(), - S::Line(it) => it.area(), - S::QuadBez(it) => it.area(), - S::Rect(it) => it.area(), - S::RoundedRect(it) => it.area(), - S::External(it) => it.area(), - } + match_shape!(self, it, it.area()) } fn winding(&self, pt: Point) -> i32 { - use StaticShape as S; - match self { - S::PathSeg(it) => it.winding(pt), - S::Arc(it) => it.winding(pt), - S::BezPath(it) => it.winding(pt), - S::Circle(it) => it.winding(pt), - S::CircleSegment(it) => it.winding(pt), - S::CubicBez(it) => it.winding(pt), - S::Ellipse(it) => it.winding(pt), - S::Line(it) => it.winding(pt), - S::QuadBez(it) => it.winding(pt), - S::Rect(it) => it.winding(pt), - S::RoundedRect(it) => it.winding(pt), - S::External(it) => it.winding(pt), - } + match_shape!(self, it, it.winding(pt)) } fn bounding_box(&self) -> Rect { - use StaticShape as S; - match self { - S::PathSeg(it) => it.bounding_box(), - S::Arc(it) => it.bounding_box(), - S::BezPath(it) => it.bounding_box(), - S::Circle(it) => it.bounding_box(), - - S::CircleSegment(it) => it.bounding_box(), - S::CubicBez(it) => it.bounding_box(), - S::Ellipse(it) => it.bounding_box(), - S::Line(it) => it.bounding_box(), - S::QuadBez(it) => it.bounding_box(), - S::Rect(it) => it.bounding_box(), - S::RoundedRect(it) => it.bounding_box(), - S::External(it) => it.bounding_box(), - } + match_shape!(self, it, it.bounding_box()) } } From 5e6a4a40a8264a592a6080a89b0cc9900a53bdce Mon Sep 17 00:00:00 2001 From: matt rice Date: Wed, 29 May 2024 13:10:56 -0700 Subject: [PATCH 5/8] appease rustfmt and clippy --- src/static_shape.rs | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/static_shape.rs b/src/static_shape.rs index fd97edb4..ea1c8c09 100644 --- a/src/static_shape.rs +++ b/src/static_shape.rs @@ -1,6 +1,8 @@ // Copyright 2024 the Kurbo Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +#![allow(unused_qualifications)] + use crate::{Point, Rect, Shape}; use alloc::boxed::Box; @@ -65,7 +67,7 @@ where /// Corresponds to a `QuadBez` QuadBez(crate::QuadBez), /// Corresponds to a `Rect` - Rect(crate::Rect), + Rect(Rect), /// Corresponds to a `RoundedRect` RoundedRect(crate::RoundedRect), /// A type implementing shape that may be defined by an external crate. @@ -107,23 +109,22 @@ impl StaticShape { } macro_rules! match_shape { - ($x:ident, $it:ident, $e: expr) => {{ - use StaticShape as S; + ($x:ident, $it:ident, $e: expr) => { match $x { - S::PathSeg($it) => $e, - S::Arc($it) => $e, - S::BezPath($it) => $e, - S::Circle($it) => $e, - S::CircleSegment($it) => $e, - S::CubicBez($it) => $e, - S::Ellipse($it) => $e, - S::Line($it) => $e, - S::QuadBez($it) => $e, - S::Rect($it) => $e, - S::RoundedRect($it) => $e, - S::External($it) => $e, + StaticShape::PathSeg($it) => $e, + StaticShape::Arc($it) => $e, + StaticShape::BezPath($it) => $e, + StaticShape::Circle($it) => $e, + StaticShape::CircleSegment($it) => $e, + StaticShape::CubicBez($it) => $e, + StaticShape::Ellipse($it) => $e, + StaticShape::Line($it) => $e, + StaticShape::QuadBez($it) => $e, + StaticShape::Rect($it) => $e, + StaticShape::RoundedRect($it) => $e, + StaticShape::External($it) => $e, } - }} + }; } impl Shape for StaticShape @@ -132,11 +133,11 @@ where { type PathElementsIter<'iter> = Box + 'iter> where External: 'iter; fn path_elements(&self, tol: f64) -> Box + '_> { - match_shape!(self, it, Box::new(it.path_elements(tol))) + match_shape!(self, it, Box::new(it.path_elements(tol))) } fn perimeter(&self, acc: f64) -> f64 { - match_shape!(self, it, it.perimeter(acc)) + match_shape!(self, it, it.perimeter(acc)) } fn area(&self) -> f64 { From 4a31d30e7b4c63a181967eb2a98e579b66bac3b4 Mon Sep 17 00:00:00 2001 From: matt rice Date: Thu, 30 May 2024 00:41:44 -0700 Subject: [PATCH 6/8] rename StaticShape to to PrimitiveShape --- src/lib.rs | 4 +- src/{static_shape.rs => primitive_shape.rs} | 44 ++++++++++----------- 2 files changed, 24 insertions(+), 24 deletions(-) rename src/{static_shape.rs => primitive_shape.rs} (78%) diff --git a/src/lib.rs b/src/lib.rs index a9d7570e..fdc7ca79 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,7 +108,7 @@ mod rounded_rect_radii; mod shape; pub mod simplify; mod size; -mod static_shape; +mod primitive_shape; mod stroke; #[cfg(feature = "std")] mod svg; @@ -133,7 +133,7 @@ pub use crate::rounded_rect::*; pub use crate::rounded_rect_radii::*; pub use crate::shape::*; pub use crate::size::*; -pub use crate::static_shape::*; +pub use crate::primitive_shape::*; pub use crate::stroke::*; #[cfg(feature = "std")] pub use crate::svg::*; diff --git a/src/static_shape.rs b/src/primitive_shape.rs similarity index 78% rename from src/static_shape.rs rename to src/primitive_shape.rs index ea1c8c09..32c9f695 100644 --- a/src/static_shape.rs +++ b/src/primitive_shape.rs @@ -44,7 +44,7 @@ mod _never_shape { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[non_exhaustive] -pub enum StaticShape +pub enum PrimitiveShape where External: Shape, { @@ -76,7 +76,7 @@ where macro_rules! from_shape { ($it: ident) => { - impl From for StaticShape { + impl From for PrimitiveShape { fn from(it: crate::$it) -> Self { Self::$it(it) } @@ -96,38 +96,38 @@ from_shape!(QuadBez); from_shape!(Rect); from_shape!(RoundedRect); -impl StaticShape { +impl PrimitiveShape { /// Builds a static shape from an external shape implementation. /// /// For a kurbo provided shape implementation, you would normally use the `from` impl instead. - pub fn from_external_shape(shape: External) -> StaticShape + pub fn from_external_shape(shape: External) -> PrimitiveShape where External: Shape, { - StaticShape::External(shape) + PrimitiveShape::External(shape) } } macro_rules! match_shape { ($x:ident, $it:ident, $e: expr) => { match $x { - StaticShape::PathSeg($it) => $e, - StaticShape::Arc($it) => $e, - StaticShape::BezPath($it) => $e, - StaticShape::Circle($it) => $e, - StaticShape::CircleSegment($it) => $e, - StaticShape::CubicBez($it) => $e, - StaticShape::Ellipse($it) => $e, - StaticShape::Line($it) => $e, - StaticShape::QuadBez($it) => $e, - StaticShape::Rect($it) => $e, - StaticShape::RoundedRect($it) => $e, - StaticShape::External($it) => $e, + PrimitiveShape::PathSeg($it) => $e, + PrimitiveShape::Arc($it) => $e, + PrimitiveShape::BezPath($it) => $e, + PrimitiveShape::Circle($it) => $e, + PrimitiveShape::CircleSegment($it) => $e, + PrimitiveShape::CubicBez($it) => $e, + PrimitiveShape::Ellipse($it) => $e, + PrimitiveShape::Line($it) => $e, + PrimitiveShape::QuadBez($it) => $e, + PrimitiveShape::Rect($it) => $e, + PrimitiveShape::RoundedRect($it) => $e, + PrimitiveShape::External($it) => $e, } }; } -impl Shape for StaticShape +impl Shape for PrimitiveShape where External: Shape, { @@ -160,15 +160,15 @@ mod test { fn test_collection() { let r = crate::Rect::from_origin_size((0.0, 0.0), (1.0, 1.0)); let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); - let shapes: Vec = vec![r.into(), l.into()]; - assert_eq!(shapes, vec![StaticShape::Rect(r), StaticShape::Line(l),]); + let shapes: Vec = vec![r.into(), l.into()]; + assert_eq!(shapes, vec![PrimitiveShape::Rect(r), PrimitiveShape::Line(l),]); } #[test] fn test_external() { let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); assert_eq!( - StaticShape::from_external_shape(l), - StaticShape::External(l) + PrimitiveShape::from_external_shape(l), + PrimitiveShape::External(l) ); } } From c60ab6259efb9f3461d62cd4b09615804e5aff21 Mon Sep 17 00:00:00 2001 From: matt rice Date: Thu, 30 May 2024 00:47:06 -0700 Subject: [PATCH 7/8] rustfmt --- src/lib.rs | 4 ++-- src/primitive_shape.rs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fdc7ca79..ba55262a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ mod mindist; pub mod offset; mod param_curve; mod point; +mod primitive_shape; mod quadbez; mod quadspline; mod rect; @@ -108,7 +109,6 @@ mod rounded_rect_radii; mod shape; pub mod simplify; mod size; -mod primitive_shape; mod stroke; #[cfg(feature = "std")] mod svg; @@ -126,6 +126,7 @@ pub use crate::insets::*; pub use crate::line::*; pub use crate::param_curve::*; pub use crate::point::*; +pub use crate::primitive_shape::*; pub use crate::quadbez::*; pub use crate::quadspline::*; pub use crate::rect::*; @@ -133,7 +134,6 @@ pub use crate::rounded_rect::*; pub use crate::rounded_rect_radii::*; pub use crate::shape::*; pub use crate::size::*; -pub use crate::primitive_shape::*; pub use crate::stroke::*; #[cfg(feature = "std")] pub use crate::svg::*; diff --git a/src/primitive_shape.rs b/src/primitive_shape.rs index 32c9f695..d830de47 100644 --- a/src/primitive_shape.rs +++ b/src/primitive_shape.rs @@ -161,7 +161,10 @@ mod test { let r = crate::Rect::from_origin_size((0.0, 0.0), (1.0, 1.0)); let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); let shapes: Vec = vec![r.into(), l.into()]; - assert_eq!(shapes, vec![PrimitiveShape::Rect(r), PrimitiveShape::Line(l),]); + assert_eq!( + shapes, + vec![PrimitiveShape::Rect(r), PrimitiveShape::Line(l),] + ); } #[test] fn test_external() { From cd90bf4d4d5a4130ac2c1b03b95e5bc943ec1e2f Mon Sep 17 00:00:00 2001 From: matt rice Date: Fri, 21 Jun 2024 18:56:00 -0700 Subject: [PATCH 8/8] Rename `ConcreteShape` --- src/primitive_shape.rs | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/primitive_shape.rs b/src/primitive_shape.rs index d830de47..d4619613 100644 --- a/src/primitive_shape.rs +++ b/src/primitive_shape.rs @@ -44,7 +44,7 @@ mod _never_shape { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[non_exhaustive] -pub enum PrimitiveShape +pub enum ConcreteShape where External: Shape, { @@ -76,7 +76,7 @@ where macro_rules! from_shape { ($it: ident) => { - impl From for PrimitiveShape { + impl From for ConcreteShape { fn from(it: crate::$it) -> Self { Self::$it(it) } @@ -96,38 +96,38 @@ from_shape!(QuadBez); from_shape!(Rect); from_shape!(RoundedRect); -impl PrimitiveShape { +impl ConcreteShape { /// Builds a static shape from an external shape implementation. /// /// For a kurbo provided shape implementation, you would normally use the `from` impl instead. - pub fn from_external_shape(shape: External) -> PrimitiveShape + pub fn from_external_shape(shape: External) -> ConcreteShape where External: Shape, { - PrimitiveShape::External(shape) + ConcreteShape::External(shape) } } macro_rules! match_shape { ($x:ident, $it:ident, $e: expr) => { match $x { - PrimitiveShape::PathSeg($it) => $e, - PrimitiveShape::Arc($it) => $e, - PrimitiveShape::BezPath($it) => $e, - PrimitiveShape::Circle($it) => $e, - PrimitiveShape::CircleSegment($it) => $e, - PrimitiveShape::CubicBez($it) => $e, - PrimitiveShape::Ellipse($it) => $e, - PrimitiveShape::Line($it) => $e, - PrimitiveShape::QuadBez($it) => $e, - PrimitiveShape::Rect($it) => $e, - PrimitiveShape::RoundedRect($it) => $e, - PrimitiveShape::External($it) => $e, + ConcreteShape::PathSeg($it) => $e, + ConcreteShape::Arc($it) => $e, + ConcreteShape::BezPath($it) => $e, + ConcreteShape::Circle($it) => $e, + ConcreteShape::CircleSegment($it) => $e, + ConcreteShape::CubicBez($it) => $e, + ConcreteShape::Ellipse($it) => $e, + ConcreteShape::Line($it) => $e, + ConcreteShape::QuadBez($it) => $e, + ConcreteShape::Rect($it) => $e, + ConcreteShape::RoundedRect($it) => $e, + ConcreteShape::External($it) => $e, } }; } -impl Shape for PrimitiveShape +impl Shape for ConcreteShape where External: Shape, { @@ -160,18 +160,18 @@ mod test { fn test_collection() { let r = crate::Rect::from_origin_size((0.0, 0.0), (1.0, 1.0)); let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); - let shapes: Vec = vec![r.into(), l.into()]; + let shapes: Vec = vec![r.into(), l.into()]; assert_eq!( shapes, - vec![PrimitiveShape::Rect(r), PrimitiveShape::Line(l),] + vec![ConcreteShape::Rect(r), ConcreteShape::Line(l),] ); } #[test] fn test_external() { let l = crate::Line::new((0.0, 0.0), (0.5, 0.5)); assert_eq!( - PrimitiveShape::from_external_shape(l), - PrimitiveShape::External(l) + ConcreteShape::from_external_shape(l), + ConcreteShape::External(l) ); } }