Skip to main content

kcl_lib/std/
mod.rs

1//! Functions implemented for language execution.
2
3pub mod appearance;
4pub mod args;
5pub mod array;
6pub mod assert;
7pub mod axis_or_reference;
8pub mod chamfer;
9pub mod clone;
10pub mod constraints;
11pub mod csg;
12pub mod edge;
13pub mod extrude;
14pub mod faces;
15pub mod fail;
16pub mod fillet;
17pub mod gdt;
18pub mod helix;
19pub mod ids;
20pub mod loft;
21pub mod math;
22pub mod mirror;
23pub mod patterns;
24pub mod planes;
25pub(crate) mod region_consumption;
26pub mod revolve;
27pub mod runtime;
28pub mod segment;
29pub mod shapes;
30pub mod shell;
31pub mod sketch;
32pub(crate) mod solid_consumption;
33pub(crate) mod solver;
34pub mod string;
35pub mod surfaces;
36pub mod sweep;
37pub mod transform;
38pub mod utils;
39pub mod view;
40
41use anyhow::Result;
42pub use args::Args;
43use futures::future::FutureExt;
44
45use crate::errors::KclError;
46use crate::execution::ConsumedRegionOperation;
47use crate::execution::ExecState;
48use crate::execution::KclValue;
49use crate::execution::KclValueControlFlow;
50use crate::execution::types::PrimitiveType;
51
52pub type StdFn =
53    fn(
54        &mut ExecState,
55        Args,
56    ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<KclValueControlFlow, KclError>> + Send + '_>>;
57
58#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
59pub(crate) enum ConsumedSolidArgCheck {
60    #[default]
61    Error,
62    WarnDeprecated,
63}
64
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub(crate) enum ConsumedRegionDuplicatePolicy {
67    Reject,
68    Deduplicate,
69}
70
71#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72pub(crate) enum ConsumedRegionAliasPolicy {
73    None,
74    Reject(&'static str),
75    Preserve(&'static str),
76}
77
78#[derive(Clone, Copy, Debug, PartialEq, Eq)]
79pub(crate) struct ConsumedRegionArg {
80    pub(crate) operation: ConsumedRegionOperation,
81    pub(crate) duplicate_policy: ConsumedRegionDuplicatePolicy,
82    pub(crate) alias_policy: ConsumedRegionAliasPolicy,
83    pub(crate) stale_region_policy: StaleRegionPolicy,
84}
85
86impl ConsumedRegionArg {
87    pub(crate) const fn new(operation: ConsumedRegionOperation) -> Self {
88        Self {
89            operation,
90            duplicate_policy: ConsumedRegionDuplicatePolicy::Reject,
91            alias_policy: ConsumedRegionAliasPolicy::None,
92            stale_region_policy: StaleRegionPolicy::Error,
93        }
94    }
95
96    pub(crate) const fn reject_alias_with(mut self, arg_name: &'static str) -> Self {
97        self.alias_policy = ConsumedRegionAliasPolicy::Reject(arg_name);
98        self
99    }
100
101    pub(crate) const fn preserve_alias_with(mut self, arg_name: &'static str) -> Self {
102        self.alias_policy = ConsumedRegionAliasPolicy::Preserve(arg_name);
103        self
104    }
105
106    pub(crate) const fn deduplicate(mut self) -> Self {
107        self.duplicate_policy = ConsumedRegionDuplicatePolicy::Deduplicate;
108        self
109    }
110
111    pub(crate) const fn warn_if_already_consumed(mut self) -> Self {
112        self.stale_region_policy = StaleRegionPolicy::Warning;
113        self
114    }
115}
116
117#[derive(Clone, Copy, Debug, PartialEq, Eq)]
118pub(crate) enum StaleRegionPolicy {
119    Error,
120    Warning,
121}
122
123#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
124pub(crate) enum RegionBehavior {
125    /// Warn when a consumed region reaches a Rust-backed stdlib function.
126    #[default]
127    WarnOnConsumed,
128    /// Apply the configured stale-region policy and record the specified inputs
129    /// as consumed after success.
130    Consume(ConsumedRegionArg),
131    /// The function reads stored region data without sending its object ID to the engine.
132    ReadLocal,
133}
134
135impl RegionBehavior {
136    pub(crate) const fn stale_region_policy(self) -> Option<StaleRegionPolicy> {
137        match self {
138            Self::WarnOnConsumed => Some(StaleRegionPolicy::Warning),
139            Self::Consume(policy) => Some(policy.stale_region_policy),
140            Self::ReadLocal => None,
141        }
142    }
143}
144
145#[derive(Clone, Debug, PartialEq, Eq)]
146pub struct StdFnProps {
147    pub name: String,
148    pub(crate) consumed_solid_arg_check: ConsumedSolidArgCheck,
149    pub(crate) region_behavior: RegionBehavior,
150    /// Set for the few builtins that call back into KCL (map, reduce,
151    /// patternTransform): the machine executor routes them to a resumable
152    /// entry so their callbacks run on the machine's continuation stack
153    /// instead of re-entering natively. The recursive executor ignores this.
154    pub(crate) resumable: Option<ResumableKind>,
155}
156
157/// Which resumable builtin this is. See
158/// `crate::execution::machine`'s resume continuations.
159#[derive(Clone, Copy, Debug, PartialEq, Eq)]
160pub(crate) enum ResumableKind {
161    Map,
162    Reduce,
163    PatternTransform,
164    PatternTransform2d,
165}
166
167impl StdFnProps {
168    pub(crate) fn default(name: &str) -> Self {
169        Self {
170            name: name.to_owned(),
171            consumed_solid_arg_check: Default::default(),
172            region_behavior: Default::default(),
173            resumable: None,
174        }
175    }
176
177    pub(crate) fn resumable(mut self, kind: ResumableKind) -> Self {
178        self.resumable = Some(kind);
179        self
180    }
181
182    pub(crate) fn warn_deprecated_on_consumed_solid_args(mut self) -> Self {
183        self.consumed_solid_arg_check = ConsumedSolidArgCheck::WarnDeprecated;
184        self
185    }
186
187    pub(crate) fn consumes_regions(mut self, consumed_region_arg: ConsumedRegionArg) -> Self {
188        self.region_behavior = RegionBehavior::Consume(consumed_region_arg);
189        self
190    }
191
192    pub(crate) fn reads_regions_locally(mut self) -> Self {
193        self.region_behavior = RegionBehavior::ReadLocal;
194        self
195    }
196}
197
198/// Resolves a Rust-backed standard-library function and its execution policies.
199///
200/// When registering a new function, start with `StdFnProps::default(...)`. Its
201/// fully qualified name is used in diagnostics. Then add modifiers according to
202/// how the function handles values consumed by earlier engine operations:
203///
204/// - Keep the default region behavior if the function does not accept Regions,
205///   or may use a Region's engine UUID without consuming it. A stale Region
206///   produces a warning and the call continues.
207/// - Use [`StdFnProps::reads_regions_locally`] only when the function itself
208///   uses stored KCL data and never sends an input Region's UUID to the engine.
209///   Calls made by callbacks or KCL wrappers apply their own policies.
210/// - Use [`StdFnProps::consumes_regions`] when a successful call consumes Regions
211///   in its unlabeled input. By default, the function rejects stale Regions,
212///   rejects duplicate Regions in that input, and records the Regions as consumed
213///   after success. The modifiers define engine-specific exceptions:
214///   - [`ConsumedRegionArg::warn_if_already_consumed`] warns instead of rejecting
215///     stale Regions.
216///   - [`ConsumedRegionArg::deduplicate`] allows duplicate Regions in the input.
217///   - [`ConsumedRegionArg::reject_alias_with`] rejects a Region that is also
218///     passed in the named argument.
219///   - [`ConsumedRegionArg::preserve_alias_with`] does not record a Region as
220///     consumed when it is also passed in the named argument.
221/// - Keep the default consumed-solid behavior for new functions. Use
222///   [`StdFnProps::warn_deprecated_on_consumed_solid_args`] only as a temporary
223///   compatibility exception that warns instead of rejecting the call.
224///
225/// Region and solid policies are independent, so their modifiers may be chained.
226pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProps) {
227    match (path, fn_name) {
228        ("gdt", "datum") => (
229            |e, a| Box::pin(crate::std::gdt::datum(e, a).map(|r| r.map(KclValue::continue_))),
230            StdFnProps::default("std::gdt::datum"),
231        ),
232        ("gdt", "flatness") => (
233            |e, a| Box::pin(crate::std::gdt::flatness(e, a).map(|r| r.map(KclValue::continue_))),
234            StdFnProps::default("std::gdt::flatness"),
235        ),
236        ("gdt", "straightness") => (
237            |e, a| Box::pin(crate::std::gdt::straightness(e, a).map(|r| r.map(KclValue::continue_))),
238            StdFnProps::default("std::gdt::straightness"),
239        ),
240        ("gdt", "circularity") => (
241            |e, a| Box::pin(crate::std::gdt::circularity(e, a).map(|r| r.map(KclValue::continue_))),
242            StdFnProps::default("std::gdt::circularity"),
243        ),
244        ("gdt", "cylindricity") => (
245            |e, a| Box::pin(crate::std::gdt::cylindricity(e, a).map(|r| r.map(KclValue::continue_))),
246            StdFnProps::default("std::gdt::cylindricity"),
247        ),
248        ("gdt", "concentricity") => (
249            |e, a| Box::pin(crate::std::gdt::concentricity(e, a).map(|r| r.map(KclValue::continue_))),
250            StdFnProps::default("std::gdt::concentricity"),
251        ),
252        ("gdt", "symmetry") => (
253            |e, a| Box::pin(crate::std::gdt::symmetry(e, a).map(|r| r.map(KclValue::continue_))),
254            StdFnProps::default("std::gdt::symmetry"),
255        ),
256        ("gdt", "runout") => (
257            |e, a| Box::pin(crate::std::gdt::runout(e, a).map(|r| r.map(KclValue::continue_))),
258            StdFnProps::default("std::gdt::runout"),
259        ),
260        ("gdt", "angularity") => (
261            |e, a| Box::pin(crate::std::gdt::angularity(e, a).map(|r| r.map(KclValue::continue_))),
262            StdFnProps::default("std::gdt::angularity"),
263        ),
264        ("gdt", "perpendicularity") => (
265            |e, a| Box::pin(crate::std::gdt::perpendicularity(e, a).map(|r| r.map(KclValue::continue_))),
266            StdFnProps::default("std::gdt::perpendicularity"),
267        ),
268        ("gdt", "parallelism") => (
269            |e, a| Box::pin(crate::std::gdt::parallelism(e, a).map(|r| r.map(KclValue::continue_))),
270            StdFnProps::default("std::gdt::parallelism"),
271        ),
272        ("gdt", "annotation") => (
273            |e, a| Box::pin(crate::std::gdt::annotation(e, a).map(|r| r.map(KclValue::continue_))),
274            StdFnProps::default("std::gdt::annotation"),
275        ),
276        ("gdt", "note") => (
277            |e, a| Box::pin(crate::std::gdt::note(e, a).map(|r| r.map(KclValue::continue_))),
278            StdFnProps::default("std::gdt::note"),
279        ),
280        ("gdt", "distance") => (
281            |e, a| Box::pin(crate::std::gdt::distance(e, a).map(|r| r.map(KclValue::continue_))),
282            StdFnProps::default("std::gdt::distance"),
283        ),
284        ("gdt", "profile") => (
285            |e, a| Box::pin(crate::std::gdt::profile(e, a).map(|r| r.map(KclValue::continue_))),
286            StdFnProps::default("std::gdt::profile"),
287        ),
288        ("gdt", "profileLine") => (
289            |e, a| Box::pin(crate::std::gdt::profile_line(e, a).map(|r| r.map(KclValue::continue_))),
290            StdFnProps::default("std::gdt::profileLine"),
291        ),
292        ("gdt", "profileSurface") => (
293            |e, a| Box::pin(crate::std::gdt::profile_surface(e, a).map(|r| r.map(KclValue::continue_))),
294            StdFnProps::default("std::gdt::profileSurface"),
295        ),
296        ("gdt", "position") => (
297            |e, a| Box::pin(crate::std::gdt::position(e, a).map(|r| r.map(KclValue::continue_))),
298            StdFnProps::default("std::gdt::position"),
299        ),
300        ("math", "cos") => (
301            |e, a| Box::pin(crate::std::math::cos(e, a).map(|r| r.map(KclValue::continue_))),
302            StdFnProps::default("std::math::cos"),
303        ),
304        ("math", "sin") => (
305            |e, a| Box::pin(crate::std::math::sin(e, a).map(|r| r.map(KclValue::continue_))),
306            StdFnProps::default("std::math::sin"),
307        ),
308        ("math", "tan") => (
309            |e, a| Box::pin(crate::std::math::tan(e, a).map(|r| r.map(KclValue::continue_))),
310            StdFnProps::default("std::math::tan"),
311        ),
312        ("math", "acos") => (
313            |e, a| Box::pin(crate::std::math::acos(e, a).map(|r| r.map(KclValue::continue_))),
314            StdFnProps::default("std::math::acos"),
315        ),
316        ("math", "asin") => (
317            |e, a| Box::pin(crate::std::math::asin(e, a).map(|r| r.map(KclValue::continue_))),
318            StdFnProps::default("std::math::asin"),
319        ),
320        ("math", "atan") => (
321            |e, a| Box::pin(crate::std::math::atan(e, a).map(|r| r.map(KclValue::continue_))),
322            StdFnProps::default("std::math::atan"),
323        ),
324        ("math", "atan2") => (
325            |e, a| Box::pin(crate::std::math::atan2(e, a).map(|r| r.map(KclValue::continue_))),
326            StdFnProps::default("std::math::atan2"),
327        ),
328        ("math", "sqrt") => (
329            |e, a| Box::pin(crate::std::math::sqrt(e, a).map(|r| r.map(KclValue::continue_))),
330            StdFnProps::default("std::math::sqrt"),
331        ),
332
333        ("math", "abs") => (
334            |e, a| Box::pin(crate::std::math::abs(e, a).map(|r| r.map(KclValue::continue_))),
335            StdFnProps::default("std::math::abs"),
336        ),
337        ("math", "rem") => (
338            |e, a| Box::pin(crate::std::math::rem(e, a).map(|r| r.map(KclValue::continue_))),
339            StdFnProps::default("std::math::rem"),
340        ),
341        ("math", "round") => (
342            |e, a| Box::pin(crate::std::math::round(e, a).map(|r| r.map(KclValue::continue_))),
343            StdFnProps::default("std::math::round"),
344        ),
345        ("math", "floor") => (
346            |e, a| Box::pin(crate::std::math::floor(e, a).map(|r| r.map(KclValue::continue_))),
347            StdFnProps::default("std::math::floor"),
348        ),
349        ("math", "ceil") => (
350            |e, a| Box::pin(crate::std::math::ceil(e, a).map(|r| r.map(KclValue::continue_))),
351            StdFnProps::default("std::math::ceil"),
352        ),
353        ("math", "min") => (
354            |e, a| Box::pin(crate::std::math::min(e, a).map(|r| r.map(KclValue::continue_))),
355            StdFnProps::default("std::math::min"),
356        ),
357        ("math", "max") => (
358            |e, a| Box::pin(crate::std::math::max(e, a).map(|r| r.map(KclValue::continue_))),
359            StdFnProps::default("std::math::max"),
360        ),
361        ("math", "pow") => (
362            |e, a| Box::pin(crate::std::math::pow(e, a).map(|r| r.map(KclValue::continue_))),
363            StdFnProps::default("std::math::pow"),
364        ),
365        ("math", "log") => (
366            |e, a| Box::pin(crate::std::math::log(e, a).map(|r| r.map(KclValue::continue_))),
367            StdFnProps::default("std::math::log"),
368        ),
369        ("math", "log2") => (
370            |e, a| Box::pin(crate::std::math::log2(e, a).map(|r| r.map(KclValue::continue_))),
371            StdFnProps::default("std::math::log2"),
372        ),
373        ("math", "log10") => (
374            |e, a| Box::pin(crate::std::math::log10(e, a).map(|r| r.map(KclValue::continue_))),
375            StdFnProps::default("std::math::log10"),
376        ),
377        ("math", "ln") => (
378            |e, a| Box::pin(crate::std::math::ln(e, a).map(|r| r.map(KclValue::continue_))),
379            StdFnProps::default("std::math::ln"),
380        ),
381        ("math", "legLen") => (
382            |e, a| Box::pin(crate::std::math::leg_length(e, a).map(|r| r.map(KclValue::continue_))),
383            StdFnProps::default("std::math::legLen"),
384        ),
385        ("math", "legAngX") => (
386            |e, a| Box::pin(crate::std::math::leg_angle_x(e, a).map(|r| r.map(KclValue::continue_))),
387            StdFnProps::default("std::math::legAngX"),
388        ),
389        ("math", "legAngY") => (
390            |e, a| Box::pin(crate::std::math::leg_angle_y(e, a).map(|r| r.map(KclValue::continue_))),
391            StdFnProps::default("std::math::legAngY"),
392        ),
393        ("sketch", "circle") => (
394            |e, a| Box::pin(crate::std::shapes::circle(e, a).map(|r| r.map(KclValue::continue_))),
395            StdFnProps::default("std::sketch::circle").reads_regions_locally(),
396        ),
397        ("sketch", "ellipse") => (
398            |e, a| Box::pin(crate::std::shapes::ellipse(e, a).map(|r| r.map(KclValue::continue_))),
399            StdFnProps::default("std::sketch::ellipse").reads_regions_locally(),
400        ),
401        ("prelude", "helix") => (
402            |e, a| Box::pin(crate::std::helix::helix(e, a).map(|r| r.map(KclValue::continue_))),
403            StdFnProps::default("std::helix"),
404        ),
405        ("transform", "mirror2d") => (
406            |e, a| Box::pin(crate::std::mirror::mirror_2d(e, a).map(|r| r.map(KclValue::continue_))),
407            StdFnProps::default("std::transform::mirror2d"),
408        ),
409        ("transform", "mirror3d") => (
410            |e, a| Box::pin(crate::std::mirror::mirror_3d(e, a).map(|r| r.map(KclValue::continue_))),
411            StdFnProps::default("std::transform::mirror3d"),
412        ),
413        ("transform", "translate") => (
414            |e, a| Box::pin(crate::std::transform::translate(e, a).map(|r| r.map(KclValue::continue_))),
415            StdFnProps::default("std::transform::translate"),
416        ),
417        ("transform", "rotate") => (
418            |e, a| Box::pin(crate::std::transform::rotate(e, a).map(|r| r.map(KclValue::continue_))),
419            StdFnProps::default("std::transform::rotate"),
420        ),
421        ("transform", "scale") => (
422            |e, a| Box::pin(crate::std::transform::scale(e, a).map(|r| r.map(KclValue::continue_))),
423            StdFnProps::default("std::transform::scale"),
424        ),
425        ("transform", "hide") => (
426            |e, a| Box::pin(crate::std::transform::hide(e, a).map(|r| r.map(KclValue::continue_))),
427            StdFnProps::default("std::transform::hide").warn_deprecated_on_consumed_solid_args(),
428        ),
429        ("transform", "delete") => (
430            |e, a| Box::pin(crate::std::transform::delete(e, a).map(|r| r.map(KclValue::continue_))),
431            StdFnProps::default("std::transform::delete").consumes_regions(
432                ConsumedRegionArg::new(ConsumedRegionOperation::Delete)
433                    .deduplicate()
434                    .warn_if_already_consumed(),
435            ),
436        ),
437        ("prelude", "offsetPlane") => (
438            |e, a| Box::pin(crate::std::planes::offset_plane(e, a).map(|r| r.map(KclValue::continue_))),
439            StdFnProps::default("std::offsetPlane"),
440        ),
441        ("prelude", "assert") => (
442            |e, a| Box::pin(crate::std::assert::assert(e, a).map(|r| r.map(KclValue::continue_))),
443            StdFnProps::default("std::assert"),
444        ),
445        ("prelude", "assertIs") => (
446            |e, a| Box::pin(crate::std::assert::assert_is(e, a).map(|r| r.map(KclValue::continue_))),
447            StdFnProps::default("std::assertIs"),
448        ),
449        ("prelude", "fail") => (
450            |e, a| Box::pin(crate::std::fail::fail(e, a).map(|r| r.map(KclValue::continue_))),
451            StdFnProps::default("std::fail"),
452        ),
453        ("runtime", "exit") => (
454            |e, a| Box::pin(crate::std::runtime::exit(e, a)),
455            StdFnProps::default("std::runtime::exit"),
456        ),
457        ("string", "uppercase") => (
458            |e, a| Box::pin(crate::std::string::uppercase(e, a).map(|r| r.map(KclValue::continue_))),
459            StdFnProps::default("std::string::uppercase"),
460        ),
461        ("string", "lowercase") => (
462            |e, a| Box::pin(crate::std::string::lowercase(e, a).map(|r| r.map(KclValue::continue_))),
463            StdFnProps::default("std::string::lowercase"),
464        ),
465        ("string", "isEqual") => (
466            |e, a| Box::pin(crate::std::string::is_equal(e, a).map(|r| r.map(KclValue::continue_))),
467            StdFnProps::default("std::string::isEqual"),
468        ),
469        ("string", "trim") => (
470            |e, a| Box::pin(crate::std::string::trim(e, a).map(|r| r.map(KclValue::continue_))),
471            StdFnProps::default("std::string::trim"),
472        ),
473        ("string", "trimStart") => (
474            |e, a| Box::pin(crate::std::string::trim_start(e, a).map(|r| r.map(KclValue::continue_))),
475            StdFnProps::default("std::string::trimStart"),
476        ),
477        ("string", "trimEnd") => (
478            |e, a| Box::pin(crate::std::string::trim_end(e, a).map(|r| r.map(KclValue::continue_))),
479            StdFnProps::default("std::string::trimEnd"),
480        ),
481        ("string", "toString") => (
482            |e, a| Box::pin(crate::std::string::number_to_string(e, a).map(|r| r.map(KclValue::continue_))),
483            StdFnProps::default("std::string::toString"),
484        ),
485        ("solid", "fillet") => (
486            |e, a| Box::pin(crate::std::fillet::fillet(e, a).map(|r| r.map(KclValue::continue_))),
487            StdFnProps::default("std::solid::fillet"),
488        ),
489        ("solid", "chamfer") => (
490            |e, a| Box::pin(crate::std::chamfer::chamfer(e, a).map(|r| r.map(KclValue::continue_))),
491            StdFnProps::default("std::solid::chamfer"),
492        ),
493        ("solid", "shell") => (
494            |e, a| Box::pin(crate::std::shell::shell(e, a).map(|r| r.map(KclValue::continue_))),
495            StdFnProps::default("std::solid::shell"),
496        ),
497        ("solid", "hollow") => (
498            |e, a| Box::pin(crate::std::shell::hollow(e, a).map(|r| r.map(KclValue::continue_))),
499            StdFnProps::default("std::solid::hollow"),
500        ),
501        ("solid", "union") => (
502            |e, a| Box::pin(crate::std::csg::union(e, a).map(|r| r.map(KclValue::continue_))),
503            StdFnProps::default("std::solid::union"),
504        ),
505        ("solid", "intersect") => (
506            |e, a| Box::pin(crate::std::csg::intersect(e, a).map(|r| r.map(KclValue::continue_))),
507            StdFnProps::default("std::solid::intersect"),
508        ),
509        ("solid", "subtract") => (
510            |e, a| Box::pin(crate::std::csg::subtract(e, a).map(|r| r.map(KclValue::continue_))),
511            StdFnProps::default("std::solid::subtract"),
512        ),
513        ("solid", "patternTransform") => (
514            |e, a| Box::pin(crate::std::patterns::pattern_transform(e, a)),
515            StdFnProps::default("std::solid::patternTransform").resumable(ResumableKind::PatternTransform),
516        ),
517        ("solid", "patternLinear3d") => (
518            |e, a| Box::pin(crate::std::patterns::pattern_linear_3d(e, a).map(|r| r.map(KclValue::continue_))),
519            StdFnProps::default("std::solid::patternLinear3d"),
520        ),
521        ("solid", "patternCircular3d") => (
522            |e, a| Box::pin(crate::std::patterns::pattern_circular_3d(e, a).map(|r| r.map(KclValue::continue_))),
523            StdFnProps::default("std::solid::patternCircular3d"),
524        ),
525        ("solid", "appearance") => (
526            |e, a| Box::pin(crate::std::appearance::appearance(e, a).map(|r| r.map(KclValue::continue_))),
527            StdFnProps::default("std::solid::appearance"),
528        ),
529        ("solid", "flipSurface") => (
530            |e, a| Box::pin(crate::std::surfaces::flip_surface(e, a).map(|r| r.map(KclValue::continue_))),
531            StdFnProps::default("std::solid::flipSurface"),
532        ),
533        ("solid", "split") => (
534            |e, a| Box::pin(crate::std::csg::split(e, a).map(|r| r.map(KclValue::continue_))),
535            StdFnProps::default("std::solid::split"),
536        ),
537        ("array", "map") => (
538            |e, a| Box::pin(crate::std::array::map(e, a)),
539            StdFnProps::default("std::array::map")
540                .reads_regions_locally()
541                .resumable(ResumableKind::Map),
542        ),
543        ("array", "reduce") => (
544            |e, a| Box::pin(crate::std::array::reduce(e, a)),
545            StdFnProps::default("std::array::reduce")
546                .reads_regions_locally()
547                .resumable(ResumableKind::Reduce),
548        ),
549        ("array", "push") => (
550            |e, a| Box::pin(crate::std::array::push(e, a).map(|r| r.map(KclValue::continue_))),
551            StdFnProps::default("std::array::push").reads_regions_locally(),
552        ),
553        ("array", "pop") => (
554            |e, a| Box::pin(crate::std::array::pop(e, a).map(|r| r.map(KclValue::continue_))),
555            StdFnProps::default("std::array::pop").reads_regions_locally(),
556        ),
557        ("array", "concat") => (
558            |e, a| Box::pin(crate::std::array::concat(e, a).map(|r| r.map(KclValue::continue_))),
559            StdFnProps::default("std::array::concat").reads_regions_locally(),
560        ),
561        ("array", "slice") => (
562            |e, a| Box::pin(crate::std::array::slice(e, a).map(|r| r.map(KclValue::continue_))),
563            StdFnProps::default("std::array::slice").reads_regions_locally(),
564        ),
565        ("array", "flatten") => (
566            |e, a| Box::pin(crate::std::array::flatten(e, a).map(|r| r.map(KclValue::continue_))),
567            StdFnProps::default("std::array::flatten")
568                .warn_deprecated_on_consumed_solid_args()
569                .reads_regions_locally(),
570        ),
571        ("prelude", "clone") => (
572            |e, a| Box::pin(crate::std::clone::clone(e, a).map(|r| r.map(KclValue::continue_))),
573            StdFnProps::default("std::clone"),
574        ),
575        ("prelude", "faceId") => (
576            |e, a| Box::pin(crate::std::ids::face_id(e, a).map(|r| r.map(KclValue::continue_))),
577            StdFnProps::default("std::faceId"),
578        ),
579        ("prelude", "edgeId") => (
580            |e, a| Box::pin(crate::std::ids::edge_id(e, a).map(|r| r.map(KclValue::continue_))),
581            StdFnProps::default("std::edgeId"),
582        ),
583        ("sketch", "conic") => (
584            |e, a| Box::pin(crate::std::sketch::conic(e, a).map(|r| r.map(KclValue::continue_))),
585            StdFnProps::default("std::sketch::conic"),
586        ),
587        ("sketch", "parabolic") => (
588            |e, a| Box::pin(crate::std::sketch::parabolic(e, a).map(|r| r.map(KclValue::continue_))),
589            StdFnProps::default("std::sketch::parabolic"),
590        ),
591        ("sketch", "parabolicPoint") => (
592            |e, a| Box::pin(crate::std::sketch::parabolic_point(e, a).map(|r| r.map(KclValue::continue_))),
593            StdFnProps::default("std::sketch::parabolicPoint"),
594        ),
595        ("sketch", "hyperbolic") => (
596            |e, a| Box::pin(crate::std::sketch::hyperbolic(e, a).map(|r| r.map(KclValue::continue_))),
597            StdFnProps::default("std::sketch::hyperbolic"),
598        ),
599        ("sketch", "hyperbolicPoint") => (
600            |e, a| Box::pin(crate::std::sketch::hyperbolic_point(e, a).map(|r| r.map(KclValue::continue_))),
601            StdFnProps::default("std::sketch::hyperbolicPoint"),
602        ),
603        ("sketch", "elliptic") => (
604            |e, a| Box::pin(crate::std::sketch::elliptic(e, a).map(|r| r.map(KclValue::continue_))),
605            StdFnProps::default("std::sketch::elliptic"),
606        ),
607        ("sketch", "ellipticPoint") => (
608            |e, a| Box::pin(crate::std::sketch::elliptic_point(e, a).map(|r| r.map(KclValue::continue_))),
609            StdFnProps::default("std::sketch::ellipticPoint"),
610        ),
611        ("sketch", "rectangle") => (
612            |e, a| Box::pin(crate::std::shapes::rectangle(e, a).map(|r| r.map(KclValue::continue_))),
613            StdFnProps::default("std::sketch::rectangle").reads_regions_locally(),
614        ),
615        ("sketch", "planeOf") => (
616            |e, a| Box::pin(crate::std::planes::plane_of(e, a).map(|r| r.map(KclValue::continue_))),
617            StdFnProps::default("std::sketch::planeOf"),
618        ),
619        ("sketch", "faceOf") => (
620            |e, a| Box::pin(crate::std::faces::face_of(e, a).map(|r| r.map(KclValue::continue_))),
621            StdFnProps::default("std::sketch::faceOf"),
622        ),
623        ("sketch", "extrude") => (
624            |e, a| Box::pin(crate::std::extrude::extrude(e, a).map(|r| r.map(KclValue::continue_))),
625            StdFnProps::default("std::sketch::extrude")
626                .consumes_regions(ConsumedRegionArg::new(ConsumedRegionOperation::Extrude).reject_alias_with("to")),
627        ),
628        ("sketch", "patternTransform2d") => (
629            |e, a| Box::pin(crate::std::patterns::pattern_transform_2d(e, a)),
630            StdFnProps::default("std::sketch::patternTransform2d").resumable(ResumableKind::PatternTransform2d),
631        ),
632        ("sketch", "revolve") => (
633            |e, a| Box::pin(crate::std::revolve::revolve(e, a).map(|r| r.map(KclValue::continue_))),
634            StdFnProps::default("std::sketch::revolve")
635                .consumes_regions(ConsumedRegionArg::new(ConsumedRegionOperation::Revolve)),
636        ),
637        ("sketch", "sweep") => (
638            |e, a| Box::pin(crate::std::sweep::sweep(e, a).map(|r| r.map(KclValue::continue_))),
639            StdFnProps::default("std::sketch::sweep")
640                .consumes_regions(ConsumedRegionArg::new(ConsumedRegionOperation::Sweep).preserve_alias_with("path")),
641        ),
642        ("sketch", "loft") => (
643            |e, a| Box::pin(crate::std::loft::loft(e, a).map(|r| r.map(KclValue::continue_))),
644            StdFnProps::default("std::sketch::loft"),
645        ),
646        ("sketch", "polygon") => (
647            |e, a| Box::pin(crate::std::shapes::polygon(e, a).map(|r| r.map(KclValue::continue_))),
648            StdFnProps::default("std::sketch::polygon").reads_regions_locally(),
649        ),
650        ("sketch", "circleThreePoint") => (
651            |e, a| Box::pin(crate::std::shapes::circle_three_point(e, a).map(|r| r.map(KclValue::continue_))),
652            StdFnProps::default("std::sketch::circleThreePoint").reads_regions_locally(),
653        ),
654        ("sketch", "getCommonEdge") => (
655            |e, a| Box::pin(crate::std::edge::get_common_edge(e, a).map(|r| r.map(KclValue::continue_))),
656            StdFnProps::default("std::sketch::getCommonEdge"),
657        ),
658        ("sketch", "getBoundedEdge") => (
659            |e, a| Box::pin(crate::std::edge::get_bounded_edge(e, a).map(|r| r.map(KclValue::continue_))),
660            StdFnProps::default("std::sketch::getBoundedEdge"),
661        ),
662        ("sketch", "getNextAdjacentEdge") => (
663            |e, a| Box::pin(crate::std::edge::get_next_adjacent_edge(e, a).map(|r| r.map(KclValue::continue_))),
664            StdFnProps::default("std::sketch::getNextAdjacentEdge"),
665        ),
666        ("sketch", "getOppositeEdge") => (
667            |e, a| Box::pin(crate::std::edge::get_opposite_edge(e, a).map(|r| r.map(KclValue::continue_))),
668            StdFnProps::default("std::sketch::getOppositeEdge"),
669        ),
670        ("sketch", "getPreviousAdjacentEdge") => (
671            |e, a| Box::pin(crate::std::edge::get_previous_adjacent_edge(e, a).map(|r| r.map(KclValue::continue_))),
672            StdFnProps::default("std::sketch::getPreviousAdjacentEdge"),
673        ),
674        ("sketch", "patternLinear2d") => (
675            |e, a| Box::pin(crate::std::patterns::pattern_linear_2d(e, a).map(|r| r.map(KclValue::continue_))),
676            StdFnProps::default("std::sketch::patternLinear2d"),
677        ),
678        ("sketch", "patternCircular2d") => (
679            |e, a| Box::pin(crate::std::patterns::pattern_circular_2d(e, a).map(|r| r.map(KclValue::continue_))),
680            StdFnProps::default("std::sketch::patternCircular2d"),
681        ),
682        ("sketch", "segEnd") => (
683            |e, a| Box::pin(crate::std::segment::segment_end(e, a).map(|r| r.map(KclValue::continue_))),
684            StdFnProps::default("std::sketch::segEnd"),
685        ),
686        ("sketch", "segEndX") => (
687            |e, a| Box::pin(crate::std::segment::segment_end_x(e, a).map(|r| r.map(KclValue::continue_))),
688            StdFnProps::default("std::sketch::segEndX"),
689        ),
690        ("sketch", "segEndY") => (
691            |e, a| Box::pin(crate::std::segment::segment_end_y(e, a).map(|r| r.map(KclValue::continue_))),
692            StdFnProps::default("std::sketch::segEndY"),
693        ),
694        ("sketch", "segStart") => (
695            |e, a| Box::pin(crate::std::segment::segment_start(e, a).map(|r| r.map(KclValue::continue_))),
696            StdFnProps::default("std::sketch::segStart"),
697        ),
698        ("sketch", "segStartX") => (
699            |e, a| Box::pin(crate::std::segment::segment_start_x(e, a).map(|r| r.map(KclValue::continue_))),
700            StdFnProps::default("std::sketch::segStartX"),
701        ),
702        ("sketch", "segStartY") => (
703            |e, a| Box::pin(crate::std::segment::segment_start_y(e, a).map(|r| r.map(KclValue::continue_))),
704            StdFnProps::default("std::sketch::segStartY"),
705        ),
706        ("sketch", "lastSegX") => (
707            |e, a| Box::pin(crate::std::segment::last_segment_x(e, a).map(|r| r.map(KclValue::continue_))),
708            StdFnProps::default("std::sketch::lastSegX").reads_regions_locally(),
709        ),
710        ("sketch", "lastSegY") => (
711            |e, a| Box::pin(crate::std::segment::last_segment_y(e, a).map(|r| r.map(KclValue::continue_))),
712            StdFnProps::default("std::sketch::lastSegY").reads_regions_locally(),
713        ),
714        ("sketch", "segLen") => (
715            |e, a| Box::pin(crate::std::segment::segment_length(e, a).map(|r| r.map(KclValue::continue_))),
716            StdFnProps::default("std::sketch::segLen"),
717        ),
718        ("sketch", "segAng") => (
719            |e, a| Box::pin(crate::std::segment::segment_angle(e, a).map(|r| r.map(KclValue::continue_))),
720            StdFnProps::default("std::sketch::segAng"),
721        ),
722        ("sketch", "tangentToEnd") => (
723            |e, a| Box::pin(crate::std::segment::tangent_to_end(e, a).map(|r| r.map(KclValue::continue_))),
724            StdFnProps::default("std::sketch::tangentToEnd"),
725        ),
726        ("sketch", "profileStart") => (
727            |e, a| Box::pin(crate::std::sketch::profile_start(e, a).map(|r| r.map(KclValue::continue_))),
728            StdFnProps::default("std::sketch::profileStart").reads_regions_locally(),
729        ),
730        ("sketch", "profileStartX") => (
731            |e, a| Box::pin(crate::std::sketch::profile_start_x(e, a).map(|r| r.map(KclValue::continue_))),
732            StdFnProps::default("std::sketch::profileStartX").reads_regions_locally(),
733        ),
734        ("sketch", "profileStartY") => (
735            |e, a| Box::pin(crate::std::sketch::profile_start_y(e, a).map(|r| r.map(KclValue::continue_))),
736            StdFnProps::default("std::sketch::profileStartY").reads_regions_locally(),
737        ),
738        ("sketch", "startSketchOn") => (
739            |e, a| Box::pin(crate::std::sketch::start_sketch_on(e, a).map(|r| r.map(KclValue::continue_))),
740            StdFnProps::default("std::sketch::startSketchOn"),
741        ),
742        ("sketch", "startProfile") => (
743            |e, a| Box::pin(crate::std::sketch::start_profile(e, a).map(|r| r.map(KclValue::continue_))),
744            StdFnProps::default("std::sketch::startProfile"),
745        ),
746        ("sketch", "involuteCircular") => (
747            |e, a| Box::pin(crate::std::sketch::involute_circular(e, a).map(|r| r.map(KclValue::continue_))),
748            StdFnProps::default("std::sketch::involuteCircular"),
749        ),
750        ("sketch", "line") => (
751            |e, a| Box::pin(crate::std::sketch::line(e, a).map(|r| r.map(KclValue::continue_))),
752            StdFnProps::default("std::sketch::line"),
753        ),
754        ("sketch", "xLine") => (
755            |e, a| Box::pin(crate::std::sketch::x_line(e, a).map(|r| r.map(KclValue::continue_))),
756            StdFnProps::default("std::sketch::xLine"),
757        ),
758        ("sketch", "yLine") => (
759            |e, a| Box::pin(crate::std::sketch::y_line(e, a).map(|r| r.map(KclValue::continue_))),
760            StdFnProps::default("std::sketch::yLine"),
761        ),
762        ("sketch", "angledLine") => (
763            |e, a| Box::pin(crate::std::sketch::angled_line(e, a).map(|r| r.map(KclValue::continue_))),
764            StdFnProps::default("std::sketch::angledLine"),
765        ),
766        ("sketch", "angledLineThatIntersects") => (
767            |e, a| Box::pin(crate::std::sketch::angled_line_that_intersects(e, a).map(|r| r.map(KclValue::continue_))),
768            StdFnProps::default("std::sketch::angledLineThatIntersects"),
769        ),
770        ("sketch", "close") => (
771            |e, a| Box::pin(crate::std::sketch::close(e, a).map(|r| r.map(KclValue::continue_))),
772            StdFnProps::default("std::sketch::close"),
773        ),
774        ("sketch", "arc") => (
775            |e, a| Box::pin(crate::std::sketch::arc(e, a).map(|r| r.map(KclValue::continue_))),
776            StdFnProps::default("std::sketch::arc"),
777        ),
778        ("sketch", "tangentialArc") => (
779            |e, a| Box::pin(crate::std::sketch::tangential_arc(e, a).map(|r| r.map(KclValue::continue_))),
780            StdFnProps::default("std::sketch::tangentialArc"),
781        ),
782        ("sketch", "bezierCurve") => (
783            |e, a| Box::pin(crate::std::sketch::bezier_curve(e, a).map(|r| r.map(KclValue::continue_))),
784            StdFnProps::default("std::sketch::bezierCurve"),
785        ),
786        ("sketch", "subtract2d") => (
787            |e, a| Box::pin(crate::std::sketch::subtract_2d(e, a).map(|r| r.map(KclValue::continue_))),
788            StdFnProps::default("std::sketch::subtract2d"),
789        ),
790        ("appearance", "hexString") => (
791            |e, a| Box::pin(crate::std::appearance::hex_string(e, a).map(|r| r.map(KclValue::continue_))),
792            StdFnProps::default("std::appearance::hexString"),
793        ),
794        ("solver", "point") => (
795            |e, a| Box::pin(crate::std::constraints::point(e, a).map(|r| r.map(KclValue::continue_))),
796            StdFnProps::default("std::solver::point"),
797        ),
798        ("solver", "line") => (
799            |e, a| Box::pin(crate::std::constraints::line(e, a).map(|r| r.map(KclValue::continue_))),
800            StdFnProps::default("std::solver::line"),
801        ),
802        ("solver", "arc") => (
803            |e, a| Box::pin(crate::std::constraints::arc(e, a).map(|r| r.map(KclValue::continue_))),
804            StdFnProps::default("std::solver::arc"),
805        ),
806        ("solver", "circle") => (
807            |e, a| Box::pin(crate::std::constraints::circle(e, a).map(|r| r.map(KclValue::continue_))),
808            StdFnProps::default("std::solver::circle"),
809        ),
810        ("solver", "controlPointSpline") => (
811            |e, a| Box::pin(crate::std::constraints::control_point_spline(e, a).map(|r| r.map(KclValue::continue_))),
812            StdFnProps::default("std::solver::controlPointSpline"),
813        ),
814        ("solver", "coincident") => (
815            |e, a| Box::pin(crate::std::constraints::coincident(e, a).map(|r| r.map(KclValue::continue_))),
816            StdFnProps::default("std::solver::coincident"),
817        ),
818        ("solver", "distance") => (
819            |e, a| Box::pin(crate::std::constraints::distance(e, a).map(|r| r.map(KclValue::continue_))),
820            StdFnProps::default("std::solver::distance"),
821        ),
822        ("solver", "radius") => (
823            |e, a| Box::pin(crate::std::constraints::radius(e, a).map(|r| r.map(KclValue::continue_))),
824            StdFnProps::default("std::solver::radius"),
825        ),
826        ("solver", "diameter") => (
827            |e, a| Box::pin(crate::std::constraints::diameter(e, a).map(|r| r.map(KclValue::continue_))),
828            StdFnProps::default("std::solver::diameter"),
829        ),
830        ("solver", "horizontalDistance") => (
831            |e, a| Box::pin(crate::std::constraints::horizontal_distance(e, a).map(|r| r.map(KclValue::continue_))),
832            StdFnProps::default("std::solver::horizontalDistance"),
833        ),
834        ("solver", "verticalDistance") => (
835            |e, a| Box::pin(crate::std::constraints::vertical_distance(e, a).map(|r| r.map(KclValue::continue_))),
836            StdFnProps::default("std::solver::verticalDistance"),
837        ),
838        ("solver", "equalLength") => (
839            |e, a| Box::pin(crate::std::constraints::equal_length(e, a).map(|r| r.map(KclValue::continue_))),
840            StdFnProps::default("std::solver::equalLength"),
841        ),
842        ("solver", "midpoint") => (
843            |e, a| Box::pin(crate::std::constraints::midpoint(e, a).map(|r| r.map(KclValue::continue_))),
844            StdFnProps::default("std::solver::midpoint"),
845        ),
846        ("solver", "equalRadius") => (
847            |e, a| Box::pin(crate::std::constraints::equal_radius(e, a).map(|r| r.map(KclValue::continue_))),
848            StdFnProps::default("std::solver::equalRadius"),
849        ),
850        ("solver", "angle") => (
851            |e, a| Box::pin(crate::std::constraints::angle(e, a).map(|r| r.map(KclValue::continue_))),
852            StdFnProps::default("std::solver::angle"),
853        ),
854        ("solver", "angleDimension") => (
855            |e, a| Box::pin(crate::std::constraints::angle_dimension(e, a).map(|r| r.map(KclValue::continue_))),
856            StdFnProps::default("std::solver::angleDimension"),
857        ),
858        ("solver", "tangent") => (
859            |e, a| Box::pin(crate::std::constraints::tangent(e, a).map(|r| r.map(KclValue::continue_))),
860            StdFnProps::default("std::solver::tangent"),
861        ),
862        ("solver", "symmetric") => (
863            |e, a| Box::pin(crate::std::constraints::symmetric(e, a).map(|r| r.map(KclValue::continue_))),
864            StdFnProps::default("std::solver::symmetric"),
865        ),
866        ("solver", "horizontal") => (
867            |e, a| Box::pin(crate::std::constraints::horizontal(e, a).map(|r| r.map(KclValue::continue_))),
868            StdFnProps::default("std::solver::horizontal"),
869        ),
870        ("solver", "parallel") => (
871            |e, a| Box::pin(crate::std::constraints::parallel(e, a).map(|r| r.map(KclValue::continue_))),
872            StdFnProps::default("std::solver::parallel"),
873        ),
874        ("solver", "perpendicular") => (
875            |e, a| Box::pin(crate::std::constraints::perpendicular(e, a).map(|r| r.map(KclValue::continue_))),
876            StdFnProps::default("std::solver::perpendicular"),
877        ),
878        ("solver", "vertical") => (
879            |e, a| Box::pin(crate::std::constraints::vertical(e, a).map(|r| r.map(KclValue::continue_))),
880            StdFnProps::default("std::solver::vertical"),
881        ),
882        ("sketch", "region") => (
883            |e, a| Box::pin(crate::std::sketch::region(e, a).map(|r| r.map(KclValue::continue_))),
884            StdFnProps::default("std::sketch::region"),
885        ),
886        ("solid", "isSurface") => (
887            |e, a| Box::pin(crate::std::surfaces::is_surface(e, a).map(|r| r.map(KclValue::continue_))),
888            StdFnProps::default("std::solid::isSurface"),
889        ),
890        ("solid", "isSolid") => (
891            |e, a| Box::pin(crate::std::surfaces::is_solid(e, a).map(|r| r.map(KclValue::continue_))),
892            StdFnProps::default("std::solid::isSolid"),
893        ),
894        ("solid", "deleteFace") => (
895            |e, a| Box::pin(crate::std::surfaces::delete_face(e, a).map(|r| r.map(KclValue::continue_))),
896            StdFnProps::default("std::solid::deleteFace"),
897        ),
898        ("solid", "blend") => (
899            |e, a| Box::pin(crate::std::surfaces::blend(e, a).map(|r| r.map(KclValue::continue_))),
900            StdFnProps::default("std::solid::blend"),
901        ),
902        ("solid", "joinSurfaces") => (
903            |e, a| Box::pin(crate::std::surfaces::join(e, a).map(|r| r.map(KclValue::continue_))),
904            StdFnProps::default("std::solid::joinSurfaces"),
905        ),
906        ("view", "oriented") => (
907            |e, a| Box::pin(crate::std::view::oriented(e, a).map(|r| r.map(KclValue::continue_))),
908            StdFnProps::default("std::view::oriented"),
909        ),
910        ("view", "directed") => (
911            |e, a| Box::pin(crate::std::view::directed(e, a).map(|r| r.map(KclValue::continue_))),
912            StdFnProps::default("std::view::directed"),
913        ),
914        ("view", "named") => (
915            |e, a| Box::pin(crate::std::view::named(e, a).map(|r| r.map(KclValue::continue_))),
916            StdFnProps::default("std::view::named"),
917        ),
918        (module, fn_name) => {
919            panic!("No implementation found for {module}::{fn_name}, please add it to this big match statement")
920        }
921    }
922}
923
924pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) {
925    match (path, fn_name) {
926        ("types", "Segment") => (PrimitiveType::Segment, StdFnProps::default("std::types::Segment")),
927        ("types", "Sketch") => (PrimitiveType::Sketch, StdFnProps::default("std::types::Sketch")),
928        ("types", "Solid") => (PrimitiveType::Solid, StdFnProps::default("std::types::Solid")),
929        ("types", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::types::Plane")),
930        ("types", "Face") => (PrimitiveType::Face, StdFnProps::default("std::types::Face")),
931        ("types", "GdtAnnotation") => (
932            PrimitiveType::GdtAnnotation,
933            StdFnProps::default("std::types::GdtAnnotation"),
934        ),
935        ("types", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::types::Helix")),
936        ("types", "Edge") => (PrimitiveType::Edge, StdFnProps::default("std::types::Edge")),
937        ("types", "Axis2d") => (PrimitiveType::Axis2d, StdFnProps::default("std::types::Axis2d")),
938        ("types", "Axis3d") => (PrimitiveType::Axis3d, StdFnProps::default("std::types::Axis3d")),
939        ("types", "TaggedEdge") => (PrimitiveType::TaggedEdge, StdFnProps::default("std::types::TaggedEdge")),
940        ("types", "TaggedFace") => (PrimitiveType::TaggedFace, StdFnProps::default("std::types::TaggedFace")),
941        ("types", "BoundedEdge") => (
942            PrimitiveType::BoundedEdge,
943            StdFnProps::default("std::types::BoundedEdge"),
944        ),
945        ("view", "CameraView") => (PrimitiveType::CameraView, StdFnProps::default("std::view::CameraView")),
946        ("view", "NamedView") => (PrimitiveType::NamedView, StdFnProps::default("std::view::NamedView")),
947        _ => unreachable!(),
948    }
949}
950
951/// The default tolerance for modeling commands in millimeters.
952const DEFAULT_TOLERANCE_MM: f64 = 0.0000001;
953
954/// The default tolerance for testing the equality of points.
955/// WARNING: This must match the tolerance in engine/cpp/engine/scene/constants.h
956#[allow(clippy::excessive_precision)]
957const EQUAL_POINTS_DIST_EPSILON: f64 = 2.3283064365386962890625e-10;
958
959#[derive(Debug, Clone, Copy, PartialEq, Eq)]
960pub(crate) enum CircularDirection {
961    Counterclockwise,
962    Clockwise,
963}
964
965impl CircularDirection {
966    pub fn is_clockwise(self) -> bool {
967        match self {
968            CircularDirection::Counterclockwise => false,
969            CircularDirection::Clockwise => true,
970        }
971    }
972}