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