1use disposition_input_model::{
2 entity::{EntityDescs, EntityTypes},
3 process::Processes,
4 tag::{TagNames, TagThings},
5 theme::{
6 StyleAliases, ThemeDefault, ThemeStyles, ThemeTagThingsFocus, ThemeThingDependenciesStyles,
7 ThemeTypesStyles,
8 },
9 thing::{
10 ThingCopyText, ThingDependencies, ThingHierarchy, ThingInteractions, ThingLayouts,
11 ThingNames,
12 },
13 InputDiagram,
14};
15use disposition_model_common::{entity::EntityTooltips, theme::Css};
16
17#[derive(Clone, Copy, Debug)]
19pub struct InputDiagramMerger;
20
21impl InputDiagramMerger {
22 pub fn merge<'f, 'id>(
43 base_diagram: InputDiagram<'static>,
44 overlay_diagram: &'f InputDiagram<'id>,
45 ) -> InputDiagram<'id>
46 where
47 'id: 'f,
48 {
49 let things = Self::merge_thing_names(base_diagram.things, &overlay_diagram.things);
50 let thing_copy_text = Self::merge_thing_copy_text(
51 base_diagram.thing_copy_text,
52 &overlay_diagram.thing_copy_text,
53 );
54 let thing_hierarchy = Self::merge_thing_hierarchy(
55 base_diagram.thing_hierarchy,
56 &overlay_diagram.thing_hierarchy,
57 );
58 let thing_layouts =
59 Self::merge_thing_layouts(base_diagram.thing_layouts, &overlay_diagram.thing_layouts);
60 let thing_dependencies = Self::merge_thing_dependencies(
61 base_diagram.thing_dependencies,
62 &overlay_diagram.thing_dependencies,
63 );
64 let thing_interactions = Self::merge_thing_interactions(
65 base_diagram.thing_interactions,
66 &overlay_diagram.thing_interactions,
67 );
68 let processes = Self::merge_processes(base_diagram.processes, &overlay_diagram.processes);
69 let tags = Self::merge_tag_names(base_diagram.tags, &overlay_diagram.tags);
70 let tag_things =
71 Self::merge_tag_things(base_diagram.tag_things, &overlay_diagram.tag_things);
72 let entity_descs =
73 Self::merge_entity_descs(base_diagram.entity_descs, &overlay_diagram.entity_descs);
74 let entity_tooltips = Self::merge_entity_tooltips(
75 base_diagram.entity_tooltips,
76 &overlay_diagram.entity_tooltips,
77 );
78 let entity_types =
79 Self::merge_entity_types(base_diagram.entity_types, &overlay_diagram.entity_types);
80 let theme_default =
81 Self::merge_theme_default(base_diagram.theme_default, &overlay_diagram.theme_default);
82 let theme_types_styles = Self::merge_theme_types_styles(
83 base_diagram.theme_types_styles,
84 &overlay_diagram.theme_types_styles,
85 );
86 let theme_thing_dependencies_styles = Self::merge_theme_thing_dependencies_styles(
87 base_diagram.theme_thing_dependencies_styles,
88 &overlay_diagram.theme_thing_dependencies_styles,
89 );
90 let theme_tag_things_focus = Self::merge_theme_tag_things_focus(
91 base_diagram.theme_tag_things_focus,
92 &overlay_diagram.theme_tag_things_focus,
93 );
94 let render_options = overlay_diagram.render_options;
95 let css = Self::merge_css(base_diagram.css, &overlay_diagram.css);
96
97 InputDiagram {
98 things,
99 thing_copy_text,
100 thing_hierarchy,
101 thing_layouts,
102 thing_dependencies,
103 thing_interactions,
104 processes,
105 tags,
106 tag_things,
107 entity_descs,
108 entity_tooltips,
109 entity_types,
110 theme_default,
111 theme_types_styles,
112 theme_thing_dependencies_styles,
113 theme_tag_things_focus,
114 render_options,
115 css,
116 }
117 }
118
119 fn merge_thing_names<'id>(
120 base: ThingNames<'static>,
121 overlay: &ThingNames<'id>,
122 ) -> ThingNames<'id> {
123 let mut result = base;
124 overlay.iter().for_each(|(key, value)| {
125 result.insert(key.clone(), value.clone());
126 });
127 result
128 }
129
130 fn merge_thing_copy_text<'id>(
131 base: ThingCopyText<'static>,
132 overlay: &ThingCopyText<'id>,
133 ) -> ThingCopyText<'id> {
134 let mut result = base;
135 overlay.iter().for_each(|(key, value)| {
136 result.insert(key.clone(), value.clone());
137 });
138 result
139 }
140
141 fn merge_thing_hierarchy<'id>(
142 base: ThingHierarchy<'static>,
143 overlay: &ThingHierarchy<'id>,
144 ) -> ThingHierarchy<'id> {
145 let mut result = base;
150 overlay.iter().for_each(|(key, value)| {
151 result.insert(key.clone(), value.clone());
152 });
153 result
154 }
155
156 fn merge_thing_layouts<'id>(
157 base: ThingLayouts<'static>,
158 overlay: &ThingLayouts<'id>,
159 ) -> ThingLayouts<'id> {
160 let mut result = base;
161 overlay.iter().for_each(|(key, value)| {
162 result.insert(key.clone(), *value);
163 });
164 result
165 }
166
167 fn merge_thing_dependencies<'id>(
168 base: ThingDependencies<'static>,
169 overlay: &ThingDependencies<'id>,
170 ) -> ThingDependencies<'id> {
171 let mut result = base;
172 overlay.iter().for_each(|(key, value)| {
173 result.insert(key.clone(), value.clone());
174 });
175 result
176 }
177
178 fn merge_thing_interactions<'id>(
179 base: ThingInteractions<'static>,
180 overlay: &ThingInteractions<'id>,
181 ) -> ThingInteractions<'id> {
182 let mut result = base;
183 overlay.iter().for_each(|(key, value)| {
184 result.insert(key.clone(), value.clone());
185 });
186 result
187 }
188
189 fn merge_processes<'id>(base: Processes<'static>, overlay: &Processes<'id>) -> Processes<'id> {
190 let mut result = base;
191 overlay.iter().for_each(|(key, value)| {
192 result.insert(key.clone(), value.clone());
193 });
194 result
195 }
196
197 fn merge_tag_names<'id>(base: TagNames<'static>, overlay: &TagNames<'id>) -> TagNames<'id> {
198 let mut result = base;
199 overlay.iter().for_each(|(key, value)| {
200 result.insert(key.clone(), value.clone());
201 });
202 result
203 }
204
205 fn merge_tag_things<'id>(base: TagThings<'static>, overlay: &TagThings<'id>) -> TagThings<'id> {
206 let mut result = base;
207 overlay.iter().for_each(|(key, value)| {
208 result.insert(key.clone(), value.clone());
209 });
210 result
211 }
212
213 fn merge_entity_descs<'id>(
214 base: EntityDescs<'static>,
215 overlay: &EntityDescs<'id>,
216 ) -> EntityDescs<'id> {
217 let mut result = base;
218 overlay.iter().for_each(|(key, value)| {
219 result.insert(key.clone(), value.clone());
220 });
221 result
222 }
223
224 fn merge_entity_tooltips<'id>(
225 base: EntityTooltips<'static>,
226 overlay: &EntityTooltips<'id>,
227 ) -> EntityTooltips<'id> {
228 let mut result = base;
229 overlay.iter().for_each(|(key, value)| {
230 result.insert(key.clone(), value.clone());
231 });
232 result
233 }
234
235 fn merge_entity_types<'id>(
236 base: EntityTypes<'static>,
237 overlay: &EntityTypes<'id>,
238 ) -> EntityTypes<'id> {
239 let mut result = base;
240 overlay.iter().for_each(|(key, value)| {
241 result.insert(key.clone(), value.clone());
242 });
243 result
244 }
245
246 fn merge_theme_default<'id>(
247 base: ThemeDefault<'static>,
248 overlay: &ThemeDefault<'id>,
249 ) -> ThemeDefault<'id> {
250 let style_aliases = Self::merge_style_aliases(base.style_aliases, &overlay.style_aliases);
251 let base_styles = Self::merge_theme_styles(base.base_styles, &overlay.base_styles);
252 let process_step_selected_styles = Self::merge_theme_styles(
253 base.process_step_selected_styles,
254 &overlay.process_step_selected_styles,
255 );
256
257 let dark_mode_config = overlay.dark_mode_config;
260
261 ThemeDefault {
262 style_aliases,
263 base_styles,
264 process_step_selected_styles,
265 dark_mode_config,
266 }
267 }
268
269 fn merge_style_aliases<'id>(
270 base: StyleAliases<'static>,
271 overlay: &StyleAliases<'id>,
272 ) -> StyleAliases<'id> {
273 let mut result = base;
274 overlay.iter().for_each(|(key, value)| {
275 result.insert(key.clone(), value.clone());
276 });
277 result
278 }
279
280 fn merge_theme_styles<'id>(
281 base: ThemeStyles<'static>,
282 overlay: &ThemeStyles<'id>,
283 ) -> ThemeStyles<'id> {
284 let mut result = base;
285 overlay.iter().for_each(|(key, value)| {
286 result.insert(key.clone(), value.clone());
287 });
288 result
289 }
290
291 fn merge_theme_types_styles<'id>(
292 base: ThemeTypesStyles<'static>,
293 overlay: &ThemeTypesStyles<'id>,
294 ) -> ThemeTypesStyles<'id> {
295 let mut result = base;
296 overlay.iter().for_each(|(key, value)| {
297 result.insert(key.clone(), value.clone());
298 });
299 result
300 }
301
302 fn merge_theme_thing_dependencies_styles<'id>(
303 base: ThemeThingDependenciesStyles<'static>,
304 overlay: &ThemeThingDependenciesStyles<'id>,
305 ) -> ThemeThingDependenciesStyles<'id> {
306 let things_included_styles =
307 Self::merge_theme_styles(base.things_included_styles, &overlay.things_included_styles);
308 let things_excluded_styles =
309 Self::merge_theme_styles(base.things_excluded_styles, &overlay.things_excluded_styles);
310
311 ThemeThingDependenciesStyles {
312 things_included_styles,
313 things_excluded_styles,
314 }
315 }
316
317 fn merge_theme_tag_things_focus<'id>(
318 base: ThemeTagThingsFocus<'static>,
319 overlay: &ThemeTagThingsFocus<'id>,
320 ) -> ThemeTagThingsFocus<'id> {
321 let mut result = base;
322 overlay.iter().for_each(|(key, value)| {
323 result.insert(key.clone(), value.clone());
324 });
325 result
326 }
327
328 fn merge_css(base: Css, overlay: &Css) -> Css {
329 if overlay.is_empty() {
331 base
332 } else {
333 overlay.clone()
334 }
335 }
336}