microcad_lang/model/
element.rs1use crate::{builtin::*, model::*, render::ComputedHash, syntax::*, value::*};
7use strum::IntoStaticStr;
8
9#[derive(Clone, IntoStaticStr, Debug, Default)]
11pub enum Element {
12 #[default]
13 Group,
15
16 Workpiece(Workpiece),
20
21 BuiltinWorkpiece(BuiltinWorkpiece),
25
26 Multiplicity,
28
29 InputPlaceholder,
31}
32
33impl Element {
34 pub fn output_type(&self) -> OutputType {
36 match self {
37 Element::Workpiece(workpiece) => match workpiece.kind {
38 WorkbenchKind::Sketch => OutputType::Geometry2D,
39 WorkbenchKind::Part => OutputType::Geometry3D,
40 WorkbenchKind::Operation => OutputType::NotDetermined,
41 },
42 Element::BuiltinWorkpiece(builtin_workpiece) => match builtin_workpiece.kind {
43 BuiltinWorkbenchKind::Primitive2D => OutputType::Geometry2D,
44 BuiltinWorkbenchKind::Primitive3D => OutputType::Geometry3D,
45 BuiltinWorkbenchKind::Transform | BuiltinWorkbenchKind::Operation => {
46 builtin_workpiece.output_type
47 }
48 },
49 Element::Group | Element::Multiplicity | Element::InputPlaceholder => {
50 OutputType::NotDetermined
51 }
52 }
53 }
54
55 pub fn is_operation(&self) -> bool {
57 match self {
58 Element::BuiltinWorkpiece(builtin_workpiece) => match builtin_workpiece.kind {
59 BuiltinWorkbenchKind::Primitive2D | BuiltinWorkbenchKind::Primitive3D => false,
60 BuiltinWorkbenchKind::Operation | BuiltinWorkbenchKind::Transform => true,
61 },
62 Element::Multiplicity | Element::Group | Element::InputPlaceholder => false,
63 Element::Workpiece(workpiece) => match workpiece.kind {
64 WorkbenchKind::Part | WorkbenchKind::Sketch => false,
65 WorkbenchKind::Operation => true,
66 },
67 }
68 }
69}
70
71impl std::fmt::Display for Element {
72 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
73 let name: &'static str = self.into();
74 match &self {
75 Element::Workpiece(workpiece) => write!(f, "{workpiece}"),
76 Element::BuiltinWorkpiece(builtin_workpiece) => write!(f, "{builtin_workpiece}"),
77 _ => write!(f, "{name}"),
78 }
79 }
80}
81
82impl std::hash::Hash for Element {
83 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
84 match self {
85 Element::Group => std::mem::discriminant(&Element::Group).hash(state),
86 Element::Multiplicity => std::mem::discriminant(&Element::Multiplicity).hash(state),
87 Element::InputPlaceholder => {
88 std::mem::discriminant(&Element::InputPlaceholder).hash(state)
89 }
90 Element::Workpiece(workpiece) => workpiece.computed_hash().hash(state),
91 Element::BuiltinWorkpiece(builtin_workpiece) => {
92 builtin_workpiece.computed_hash().hash(state)
93 }
94 }
95 }
96}
97
98impl PropertiesAccess for Element {
99 fn get_property(&self, id: &Identifier) -> Option<&Value> {
100 match self {
101 Self::Workpiece(workpiece) => workpiece.get_property(id),
102 _ => unreachable!("not a workpiece element"),
103 }
104 }
105
106 fn set_property(&mut self, id: Identifier, value: Value) -> Option<Value> {
107 match self {
108 Self::Workpiece(workpiece) => workpiece.set_property(id, value),
109 _ => unreachable!("not a workpiece element"),
110 }
111 }
112
113 fn get_properties(&self) -> Option<&Properties> {
114 match self {
115 Self::Workpiece(workpiece) => workpiece.get_properties(),
116 _ => None,
117 }
118 }
119
120 fn add_properties(&mut self, props: Properties) {
121 match self {
122 Self::Workpiece(workpiece) => {
123 workpiece.add_properties(props);
124 }
125 _ => unreachable!("not a workpiece element"),
126 }
127 }
128}