microcad_lang/model/
models.rs1use crate::{model::*, src_ref::*};
7use derive_more::{Deref, DerefMut};
8use microcad_core::BooleanOp;
9
10#[derive(Debug, Default, Clone, PartialEq, Deref, DerefMut)]
12pub struct Models(Vec<Model>);
13
14impl Models {
15 pub fn single_model(&self) -> Option<Model> {
17 match self.0.len() {
18 1 => self.0.first().cloned(),
19 _ => None,
20 }
21 }
22
23 pub fn to_multiplicity(&self, src_ref: SrcRef) -> Model {
25 match self.single_model() {
26 Some(model) => model,
27 None => ModelBuilder::new(Element::Multiplicity, src_ref)
28 .add_children(self.clone())
29 .expect("No error")
30 .build(),
31 }
32 }
33
34 pub fn union(&self) -> Model {
36 self.boolean_op(microcad_core::BooleanOp::Union)
37 }
38
39 pub fn boolean_op(&self, op: BooleanOp) -> Model {
41 match self.single_model() {
42 Some(model) => model,
43 None => ModelBuilder::new(Element::BuiltinWorkpiece(op.into()), SrcRef(None))
44 .add_children(
45 [ModelBuilder::new(Element::Group, SrcRef(None))
46 .add_children(self.clone())
47 .expect("No error")
48 .build()]
49 .into_iter()
50 .collect(),
51 )
52 .expect("No error")
53 .build(),
54 }
55 }
56
57 pub fn filter_by_source_hash(&self, source_hash: u64) -> Models {
59 self.iter()
60 .filter(|model| source_hash == model.source_hash())
61 .cloned()
62 .collect()
63 }
64
65 pub fn deduce_output_type(&self) -> OutputType {
67 self.iter().map(|model| model.deduce_output_type()).fold(
68 OutputType::NotDetermined,
69 |result_output_type, model_output_type| result_output_type.merge(&model_output_type),
70 )
71 }
72}
73
74impl From<Vec<Model>> for Models {
75 fn from(value: Vec<Model>) -> Self {
76 Self(value)
77 }
78}
79
80impl From<Option<Model>> for Models {
81 fn from(value: Option<Model>) -> Self {
82 Self(value.into_iter().collect())
83 }
84}
85
86impl std::fmt::Display for Models {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 self.iter().try_for_each(|model| model.fmt(f))
89 }
90}
91
92impl FromIterator<Model> for Models {
93 fn from_iter<T: IntoIterator<Item = Model>>(iter: T) -> Self {
94 Self(iter.into_iter().collect())
95 }
96}
97
98impl TreeDisplay for Models {
99 fn tree_print(&self, f: &mut std::fmt::Formatter, depth: TreeState) -> std::fmt::Result {
100 self.iter().try_for_each(|child| child.tree_print(f, depth))
101 }
102}