microcad_lang/model/
workpiece.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Work piece element
5
6use crate::{eval::*, model::*, render::*, syntax::*, value::*};
7
8/// A workpiece is an element produced by a workbench.
9#[derive(Debug, Clone)]
10pub struct Workpiece {
11    /// Workpiece kind: `op`, `sketch`, `part`.
12    pub kind: WorkbenchKind,
13    /// Workpiece properties.
14    pub properties: Properties,
15    /// Creator symbol.
16    pub creator: Hashed<Creator>,
17}
18
19impl Workpiece {
20    /// Check the output type of the workpiece.
21    pub fn check_output_type(&self, output_type: OutputType) -> EvalResult<()> {
22        match (self.kind, output_type) {
23            (WorkbenchKind::Part, OutputType::NotDetermined) => Err(EvalError::WorkbenchNoOutput(
24                self.kind,
25                OutputType::Geometry3D,
26            )),
27            (WorkbenchKind::Sketch, OutputType::NotDetermined) => Err(
28                EvalError::WorkbenchNoOutput(self.kind, OutputType::Geometry2D),
29            ),
30            (WorkbenchKind::Part, OutputType::Geometry3D)
31            | (WorkbenchKind::Sketch, OutputType::Geometry2D)
32            | (WorkbenchKind::Operation, _) => Ok(()),
33            (WorkbenchKind::Sketch, _) => Err(EvalError::WorkbenchInvalidOutput(
34                self.kind,
35                output_type,
36                OutputType::Geometry2D,
37            )),
38            (WorkbenchKind::Part, _) => Err(EvalError::WorkbenchInvalidOutput(
39                self.kind,
40                output_type,
41                OutputType::Geometry3D,
42            )),
43        }
44    }
45}
46
47impl std::fmt::Display for Workpiece {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match self.kind {
50            WorkbenchKind::Part => write!(f, "Workpiece(part) {}", *self.creator),
51            WorkbenchKind::Sketch => write!(f, "Workpiece(sketch) {}", *self.creator),
52            WorkbenchKind::Operation => write!(f, "Workpiece(op) {}", *self.creator),
53        }
54    }
55}
56
57impl ComputedHash for Workpiece {
58    fn computed_hash(&self) -> crate::render::HashId {
59        self.creator.computed_hash()
60    }
61}
62
63impl PropertiesAccess for Workpiece {
64    fn get_property(&self, id: &Identifier) -> Option<&Value> {
65        self.properties.get(id)
66    }
67
68    fn set_property(&mut self, id: Identifier, value: Value) -> Option<Value> {
69        self.properties.insert(id, value)
70    }
71    fn get_properties(&self) -> Option<&Properties> {
72        Some(&self.properties)
73    }
74
75    fn add_properties(&mut self, props: Properties) {
76        self.properties
77            .extend(props.iter().map(|(id, prop)| (id.clone(), prop.clone())));
78    }
79}