Another project
1use bone_types::{Length, Point2, SketchEntityId, dimensioned_serde};
2use serde::{Deserialize, Serialize};
3
4#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
5#[serde(deny_unknown_fields)]
6pub struct PointData {
7 at: Point2,
8}
9
10impl PointData {
11 #[must_use]
12 pub const fn new(at: Point2) -> Self {
13 Self { at }
14 }
15
16 #[must_use]
17 pub const fn at(self) -> Point2 {
18 self.at
19 }
20
21 #[must_use]
22 pub const fn for_construction(self) -> bool {
23 true
24 }
25}
26
27#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
28#[serde(deny_unknown_fields)]
29pub struct LineData {
30 a: SketchEntityId,
31 b: SketchEntityId,
32 for_construction: bool,
33}
34
35impl LineData {
36 #[must_use]
37 pub const fn new(a: SketchEntityId, b: SketchEntityId, for_construction: bool) -> Self {
38 Self {
39 a,
40 b,
41 for_construction,
42 }
43 }
44
45 #[must_use]
46 pub const fn a(self) -> SketchEntityId {
47 self.a
48 }
49
50 #[must_use]
51 pub const fn b(self) -> SketchEntityId {
52 self.b
53 }
54
55 #[must_use]
56 pub const fn for_construction(self) -> bool {
57 self.for_construction
58 }
59
60 #[must_use]
61 pub const fn with_construction(self, for_construction: bool) -> Self {
62 Self {
63 for_construction,
64 ..self
65 }
66 }
67}
68
69#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
70#[serde(deny_unknown_fields)]
71pub struct ArcData {
72 center: SketchEntityId,
73 start: SketchEntityId,
74 end: SketchEntityId,
75 for_construction: bool,
76}
77
78impl ArcData {
79 #[must_use]
80 pub const fn new(
81 center: SketchEntityId,
82 start: SketchEntityId,
83 end: SketchEntityId,
84 for_construction: bool,
85 ) -> Self {
86 Self {
87 center,
88 start,
89 end,
90 for_construction,
91 }
92 }
93
94 #[must_use]
95 pub const fn center(self) -> SketchEntityId {
96 self.center
97 }
98
99 #[must_use]
100 pub const fn start(self) -> SketchEntityId {
101 self.start
102 }
103
104 #[must_use]
105 pub const fn end(self) -> SketchEntityId {
106 self.end
107 }
108
109 #[must_use]
110 pub const fn for_construction(self) -> bool {
111 self.for_construction
112 }
113
114 #[must_use]
115 pub const fn with_construction(self, for_construction: bool) -> Self {
116 Self {
117 for_construction,
118 ..self
119 }
120 }
121}
122
123#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
124#[serde(deny_unknown_fields)]
125pub struct CircleData {
126 center: SketchEntityId,
127 #[serde(with = "dimensioned_serde::length_si")]
128 radius: Length,
129 for_construction: bool,
130}
131
132impl CircleData {
133 #[must_use]
134 pub const fn new(center: SketchEntityId, radius: Length, for_construction: bool) -> Self {
135 Self {
136 center,
137 radius,
138 for_construction,
139 }
140 }
141
142 #[must_use]
143 pub const fn center(self) -> SketchEntityId {
144 self.center
145 }
146
147 #[must_use]
148 pub const fn radius(self) -> Length {
149 self.radius
150 }
151
152 #[must_use]
153 pub const fn for_construction(self) -> bool {
154 self.for_construction
155 }
156
157 #[must_use]
158 pub const fn with_construction(self, for_construction: bool) -> Self {
159 Self {
160 for_construction,
161 ..self
162 }
163 }
164}
165
166#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
167pub enum SketchEntityKind {
168 Point,
169 Line,
170 Arc,
171 Circle,
172}
173
174#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
175pub enum SketchEntity {
176 Point(PointData),
177 Line(LineData),
178 Arc(ArcData),
179 Circle(CircleData),
180}
181
182impl SketchEntity {
183 #[must_use]
184 pub const fn point(at: Point2) -> Self {
185 Self::Point(PointData::new(at))
186 }
187
188 #[must_use]
189 pub const fn line(a: SketchEntityId, b: SketchEntityId, for_construction: bool) -> Self {
190 Self::Line(LineData::new(a, b, for_construction))
191 }
192
193 #[must_use]
194 pub const fn arc(
195 center: SketchEntityId,
196 start: SketchEntityId,
197 end: SketchEntityId,
198 for_construction: bool,
199 ) -> Self {
200 Self::Arc(ArcData::new(center, start, end, for_construction))
201 }
202
203 #[must_use]
204 pub const fn circle(center: SketchEntityId, radius: Length, for_construction: bool) -> Self {
205 Self::Circle(CircleData::new(center, radius, for_construction))
206 }
207
208 #[must_use]
209 pub const fn for_construction(&self) -> bool {
210 match *self {
211 Self::Point(p) => p.for_construction(),
212 Self::Line(l) => l.for_construction(),
213 Self::Arc(a) => a.for_construction(),
214 Self::Circle(c) => c.for_construction(),
215 }
216 }
217
218 #[must_use]
219 pub const fn is_point(&self) -> bool {
220 matches!(self, Self::Point(_))
221 }
222
223 #[must_use]
224 pub const fn kind(&self) -> SketchEntityKind {
225 match *self {
226 Self::Point(_) => SketchEntityKind::Point,
227 Self::Line(_) => SketchEntityKind::Line,
228 Self::Arc(_) => SketchEntityKind::Arc,
229 Self::Circle(_) => SketchEntityKind::Circle,
230 }
231 }
232
233 #[must_use]
234 pub const fn references(&self) -> EntityRefs {
235 match *self {
236 Self::Point(_) => EntityRefs([None, None, None]),
237 Self::Line(l) => EntityRefs([Some(l.a()), Some(l.b()), None]),
238 Self::Arc(a) => EntityRefs([Some(a.center()), Some(a.start()), Some(a.end())]),
239 Self::Circle(c) => EntityRefs([Some(c.center()), None, None]),
240 }
241 }
242}
243
244#[derive(Copy, Clone, Debug, PartialEq)]
245pub struct EntityRefs([Option<SketchEntityId>; 3]);
246
247impl IntoIterator for EntityRefs {
248 type Item = SketchEntityId;
249 type IntoIter = core::iter::Flatten<core::array::IntoIter<Option<SketchEntityId>, 3>>;
250
251 fn into_iter(self) -> Self::IntoIter {
252 self.0.into_iter().flatten()
253 }
254}