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 creator(&self) -> Option<&Creator> {
36 match self {
37 Element::Workpiece(workpiece) => Some(&workpiece.creator),
38 Element::BuiltinWorkpiece(builtin_workpiece) => Some(&builtin_workpiece.creator),
39 _ => None,
40 }
41 }
42
43 pub fn output_type(&self) -> OutputType {
45 match self {
46 Element::Workpiece(workpiece) => match workpiece.kind {
47 WorkbenchKind::Sketch => OutputType::Geometry2D,
48 WorkbenchKind::Part => OutputType::Geometry3D,
49 WorkbenchKind::Operation => OutputType::NotDetermined,
50 },
51 Element::BuiltinWorkpiece(builtin_workpiece) => match builtin_workpiece.kind {
52 BuiltinWorkbenchKind::Primitive2D => OutputType::Geometry2D,
53 BuiltinWorkbenchKind::Primitive3D => OutputType::Geometry3D,
54 BuiltinWorkbenchKind::Transform | BuiltinWorkbenchKind::Operation => {
55 builtin_workpiece.output_type
56 }
57 },
58 Element::Group | Element::Multiplicity | Element::InputPlaceholder => {
59 OutputType::NotDetermined
60 }
61 }
62 }
63
64 pub fn is_operation(&self) -> bool {
66 match self {
67 Element::BuiltinWorkpiece(builtin_workpiece) => match builtin_workpiece.kind {
68 BuiltinWorkbenchKind::Primitive2D | BuiltinWorkbenchKind::Primitive3D => false,
69 BuiltinWorkbenchKind::Operation | BuiltinWorkbenchKind::Transform => true,
70 },
71 Element::Multiplicity | Element::Group | Element::InputPlaceholder => false,
72 Element::Workpiece(workpiece) => match workpiece.kind {
73 WorkbenchKind::Part | WorkbenchKind::Sketch => false,
74 WorkbenchKind::Operation => true,
75 },
76 }
77 }
78}
79
80impl std::fmt::Display for Element {
81 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
82 let name: &'static str = self.into();
83 match &self {
84 Element::Workpiece(workpiece) => write!(f, "{workpiece}"),
85 Element::BuiltinWorkpiece(builtin_workpiece) => write!(f, "{builtin_workpiece}"),
86 _ => write!(f, "{name}"),
87 }
88 }
89}
90
91impl std::hash::Hash for Element {
92 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
93 match self {
94 Element::Group => std::mem::discriminant(&Element::Group).hash(state),
95 Element::Multiplicity => std::mem::discriminant(&Element::Multiplicity).hash(state),
96 Element::InputPlaceholder => {
97 std::mem::discriminant(&Element::InputPlaceholder).hash(state)
98 }
99 Element::Workpiece(workpiece) => workpiece.computed_hash().hash(state),
100 Element::BuiltinWorkpiece(builtin_workpiece) => {
101 builtin_workpiece.computed_hash().hash(state)
102 }
103 }
104 }
105}
106
107impl PropertiesAccess for Element {
108 fn get_property(&self, id: &Identifier) -> Option<&Value> {
109 match self {
110 Self::Workpiece(workpiece) => workpiece.get_property(id),
111 _ => unreachable!("not a workpiece element"),
112 }
113 }
114
115 fn set_property(&mut self, id: Identifier, value: Value) -> Option<Value> {
116 match self {
117 Self::Workpiece(workpiece) => workpiece.set_property(id, value),
118 _ => unreachable!("not a workpiece element"),
119 }
120 }
121
122 fn get_properties(&self) -> Option<&Properties> {
123 match self {
124 Self::Workpiece(workpiece) => workpiece.get_properties(),
125 _ => None,
126 }
127 }
128
129 fn add_properties(&mut self, props: Properties) {
130 match self {
131 Self::Workpiece(workpiece) => {
132 workpiece.add_properties(props);
133 }
134 _ => unreachable!("not a workpiece element"),
135 }
136 }
137}