1use crate::{
2 AbstractionElement, AutosarAbstractionError, Element, IdentifiableAbstractionElement, abstraction_element,
3 datatype::DataTypeMappingSet,
4 software_component::{
5 ClientServerOperation, ModeDeclaration, ModeGroup, PPortPrototype, PortPrototype, RPortPrototype,
6 SwComponentType, VariableDataPrototype,
7 },
8};
9use autosar_data::ElementName;
10
11mod rte_event;
12
13pub use rte_event::*;
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct SwcInternalBehavior(Element);
21abstraction_element!(SwcInternalBehavior, SwcInternalBehavior);
22impl IdentifiableAbstractionElement for SwcInternalBehavior {}
23
24impl SwcInternalBehavior {
25 pub(crate) fn new(name: &str, parent: &Element) -> Result<Self, AutosarAbstractionError> {
26 let swc_internal_behavior = parent.create_named_sub_element(ElementName::SwcInternalBehavior, name)?;
27
28 Ok(Self(swc_internal_behavior))
29 }
30
31 #[must_use]
33 pub fn sw_component_type(&self) -> Option<SwComponentType> {
34 let parent = self.element().named_parent().ok()??;
35 SwComponentType::try_from(parent).ok()
36 }
37
38 pub fn create_runnable_entity(&self, name: &str) -> Result<RunnableEntity, AutosarAbstractionError> {
40 let runnalbles_elem = self.element().get_or_create_sub_element(ElementName::Runnables)?;
41 RunnableEntity::new(name, &runnalbles_elem)
42 }
43
44 pub fn runnable_entities(&self) -> impl Iterator<Item = RunnableEntity> + Send + 'static {
46 self.element()
47 .get_sub_element(ElementName::Runnables)
48 .into_iter()
49 .flat_map(|runnables| runnables.sub_elements())
50 .filter_map(|elem| RunnableEntity::try_from(elem).ok())
51 }
52
53 pub fn add_data_type_mapping_set(
55 &self,
56 data_type_mapping_set: &DataTypeMappingSet,
57 ) -> Result<(), AutosarAbstractionError> {
58 self.element()
59 .get_or_create_sub_element(ElementName::DataTypeMappingRefs)?
60 .create_sub_element(ElementName::DataTypeMappingRef)?
61 .set_reference_target(data_type_mapping_set.element())?;
62 Ok(())
63 }
64
65 pub fn data_type_mapping_sets(&self) -> impl Iterator<Item = DataTypeMappingSet> + Send + 'static {
67 self.element()
68 .get_sub_element(ElementName::DataTypeMappingRefs)
69 .into_iter()
70 .flat_map(|refs| {
71 refs.sub_elements()
72 .filter_map(|elem| elem.get_reference_target().ok())
73 .filter_map(|elem| DataTypeMappingSet::try_from(elem).ok())
74 })
75 }
76
77 pub fn create_init_event(
79 &self,
80 name: &str,
81 runnable: &RunnableEntity,
82 ) -> Result<InitEvent, AutosarAbstractionError> {
83 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
84 InitEvent::new(name, &events, runnable)
85 }
86
87 pub fn create_operation_invoked_event(
89 &self,
90 name: &str,
91 runnable: &RunnableEntity,
92 client_server_operation: &ClientServerOperation,
93 context_p_port: &PPortPrototype,
94 ) -> Result<OperationInvokedEvent, AutosarAbstractionError> {
95 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
96 OperationInvokedEvent::new(name, &events, runnable, client_server_operation, context_p_port)
97 }
98
99 pub fn create_timing_event(
101 &self,
102 name: &str,
103 runnable: &RunnableEntity,
104 period: f64,
105 ) -> Result<TimingEvent, AutosarAbstractionError> {
106 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
107 TimingEvent::new(name, &events, runnable, period)
108 }
109
110 pub fn create_background_event(
112 &self,
113 name: &str,
114 runnable: &RunnableEntity,
115 ) -> Result<BackgroundEvent, AutosarAbstractionError> {
116 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
117 BackgroundEvent::new(name, &events, runnable)
118 }
119
120 pub fn create_data_received_event<T: Into<PortPrototype> + Clone>(
122 &self,
123 name: &str,
124 runnable: &RunnableEntity,
125 variable_data_prototype: &VariableDataPrototype,
126 context_port: &T,
127 ) -> Result<DataReceivedEvent, AutosarAbstractionError> {
128 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
129 DataReceivedEvent::new(name, &events, runnable, variable_data_prototype, context_port)
130 }
131
132 pub fn create_os_task_execution_event(
134 &self,
135 name: &str,
136 runnable: &RunnableEntity,
137 ) -> Result<OsTaskExecutionEvent, AutosarAbstractionError> {
138 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
139 OsTaskExecutionEvent::new(name, &events, runnable)
140 }
141
142 pub fn create_mode_switch_event<T: Into<PortPrototype> + Clone>(
144 &self,
145 name: &str,
146 runnable: &RunnableEntity,
147 activation: ModeActivationKind,
148 context_port: &T,
149 mode_declaration: &ModeDeclaration,
150 second_mode_declaration: Option<&ModeDeclaration>,
151 ) -> Result<SwcModeSwitchEvent, AutosarAbstractionError> {
152 let events = self.element().get_or_create_sub_element(ElementName::Events)?;
153 SwcModeSwitchEvent::new(
154 name,
155 &events,
156 runnable,
157 activation,
158 context_port,
159 mode_declaration,
160 second_mode_declaration,
161 )
162 }
163
164 pub fn events(&self) -> impl Iterator<Item = RTEEvent> + Send + 'static {
166 self.element()
167 .get_sub_element(ElementName::Events)
168 .into_iter()
169 .flat_map(|events| events.sub_elements())
170 .filter_map(|elem| RTEEvent::try_from(elem).ok())
171 }
172}
173
174#[derive(Debug, Clone, PartialEq, Eq, Hash)]
178pub struct RunnableEntity(Element);
179abstraction_element!(RunnableEntity, RunnableEntity);
180impl IdentifiableAbstractionElement for RunnableEntity {}
181
182impl RunnableEntity {
183 pub(crate) fn new(name: &str, parent: &Element) -> Result<Self, AutosarAbstractionError> {
184 let runnable_entity = parent.create_named_sub_element(ElementName::RunnableEntity, name)?;
185
186 Ok(Self(runnable_entity))
187 }
188
189 #[must_use]
191 pub fn swc_internal_behavior(&self) -> Option<SwcInternalBehavior> {
192 let parent = self.element().named_parent().ok()??;
193 SwcInternalBehavior::try_from(parent).ok()
194 }
195
196 #[must_use]
198 pub fn events(&self) -> Vec<RTEEvent> {
199 let model_result = self.element().model();
200 let path_result = self.element().path();
201 if let (Ok(model), Ok(path)) = (model_result, path_result) {
202 model
203 .get_references_to(&path)
204 .iter()
205 .filter_map(|e| {
206 e.upgrade()
207 .and_then(|ref_elem| ref_elem.named_parent().ok().flatten())
208 .and_then(|elem| RTEEvent::try_from(elem).ok())
209 })
210 .collect()
211 } else {
212 vec![]
213 }
214 }
215
216 pub fn create_data_read_access<T: Into<PortPrototype> + Clone>(
220 &self,
221 name: &str,
222 data_element: &VariableDataPrototype,
223 context_port: &T,
224 ) -> Result<VariableAccess, AutosarAbstractionError> {
225 let data_accesses = self.element().get_or_create_sub_element(ElementName::DataReadAccesss)?;
226 VariableAccess::new(name, &data_accesses, data_element, &context_port.clone().into())
227 }
228
229 pub fn data_read_accesses(&self) -> impl Iterator<Item = VariableAccess> + Send + 'static {
231 self.element()
232 .get_sub_element(ElementName::DataReadAccesss)
233 .into_iter()
234 .flat_map(|data_accesses| data_accesses.sub_elements())
235 .filter_map(|elem| VariableAccess::try_from(elem).ok())
236 }
237
238 pub fn create_data_write_access<T: Into<PortPrototype> + Clone>(
242 &self,
243 name: &str,
244 data_element: &VariableDataPrototype,
245 context_port: &T,
246 ) -> Result<VariableAccess, AutosarAbstractionError> {
247 let data_accesses = self
248 .element()
249 .get_or_create_sub_element(ElementName::DataWriteAccesss)?;
250 VariableAccess::new(name, &data_accesses, data_element, &context_port.clone().into())
251 }
252
253 pub fn data_write_accesses(&self) -> impl Iterator<Item = VariableAccess> + Send + 'static {
255 self.element()
256 .get_sub_element(ElementName::DataWriteAccesss)
257 .into_iter()
258 .flat_map(|data_accesses| data_accesses.sub_elements())
259 .filter_map(|elem| VariableAccess::try_from(elem).ok())
260 }
261
262 pub fn create_data_send_point<T: Into<PortPrototype> + Clone>(
264 &self,
265 name: &str,
266 data_element: &VariableDataPrototype,
267 context_port: &T,
268 ) -> Result<VariableAccess, AutosarAbstractionError> {
269 let data_accesses = self.element().get_or_create_sub_element(ElementName::DataSendPoints)?;
270 VariableAccess::new(name, &data_accesses, data_element, &context_port.clone().into())
271 }
272
273 pub fn data_send_points(&self) -> impl Iterator<Item = VariableAccess> + Send + 'static {
275 self.element()
276 .get_sub_element(ElementName::DataSendPoints)
277 .into_iter()
278 .flat_map(|data_accesses| data_accesses.sub_elements())
279 .filter_map(|elem| VariableAccess::try_from(elem).ok())
280 }
281
282 pub fn create_data_receive_point_by_argument<T: Into<PortPrototype> + Clone>(
286 &self,
287 name: &str,
288 data_element: &VariableDataPrototype,
289 context_port: &T,
290 ) -> Result<VariableAccess, AutosarAbstractionError> {
291 let data_accesses = self
292 .element()
293 .get_or_create_sub_element(ElementName::DataReceivePointByArguments)?;
294 VariableAccess::new(name, &data_accesses, data_element, &context_port.clone().into())
295 }
296
297 pub fn data_receive_points_by_argument(&self) -> impl Iterator<Item = VariableAccess> + Send + 'static {
299 self.element()
300 .get_sub_element(ElementName::DataReceivePointByArguments)
301 .into_iter()
302 .flat_map(|data_accesses| data_accesses.sub_elements())
303 .filter_map(|elem| VariableAccess::try_from(elem).ok())
304 }
305
306 pub fn create_data_receive_point_by_value<T: Into<PortPrototype> + Clone>(
308 &self,
309 name: &str,
310 data_element: &VariableDataPrototype,
311 context_port: &T,
312 ) -> Result<VariableAccess, AutosarAbstractionError> {
313 let data_accesses = self
314 .element()
315 .get_or_create_sub_element(ElementName::DataReceivePointByValues)?;
316 VariableAccess::new(name, &data_accesses, data_element, &context_port.clone().into())
317 }
318
319 pub fn data_receive_points_by_value(&self) -> impl Iterator<Item = VariableAccess> + Send + 'static {
321 self.element()
322 .get_sub_element(ElementName::DataReceivePointByValues)
323 .into_iter()
324 .flat_map(|data_accesses| data_accesses.sub_elements())
325 .filter_map(|elem| VariableAccess::try_from(elem).ok())
326 }
327
328 pub fn create_synchronous_server_call_point(
330 &self,
331 name: &str,
332 client_server_operation: &ClientServerOperation,
333 context_r_port: &RPortPrototype,
334 ) -> Result<SynchronousServerCallPoint, AutosarAbstractionError> {
335 let server_call_points = self
336 .element()
337 .get_or_create_sub_element(ElementName::ServerCallPoints)?;
338 SynchronousServerCallPoint::new(name, &server_call_points, client_server_operation, context_r_port)
339 }
340
341 pub fn synchronous_server_call_points(&self) -> impl Iterator<Item = SynchronousServerCallPoint> + Send + 'static {
343 self.element()
344 .get_sub_element(ElementName::ServerCallPoints)
345 .into_iter()
346 .flat_map(|server_call_points| server_call_points.sub_elements())
347 .filter_map(|elem| SynchronousServerCallPoint::try_from(elem).ok())
348 }
349
350 pub fn create_mode_access_point<T: Into<PortPrototype> + Clone>(
352 &self,
353 name: &str,
354 mode_group: &ModeGroup,
355 context_port: &T,
356 ) -> Result<ModeAccessPoint, AutosarAbstractionError> {
357 let mode_access_points = self
358 .element()
359 .get_or_create_sub_element(ElementName::ModeAccessPoints)?;
360 ModeAccessPoint::new(name, &mode_access_points, mode_group, &context_port.clone().into())
361 }
362
363 pub fn mode_access_points(&self) -> impl Iterator<Item = ModeAccessPoint> + Send + 'static {
365 self.element()
366 .get_sub_element(ElementName::ModeAccessPoints)
367 .into_iter()
368 .flat_map(|mode_access_points| mode_access_points.sub_elements())
369 .filter_map(|elem| ModeAccessPoint::try_from(elem).ok())
370 }
371
372 pub fn create_mode_switch_point<T: Into<PortPrototype> + Clone>(
374 &self,
375 name: &str,
376 mode_group: &ModeGroup,
377 context_port: &T,
378 ) -> Result<ModeSwitchPoint, AutosarAbstractionError> {
379 let mode_switch_points = self
380 .element()
381 .get_or_create_sub_element(ElementName::ModeSwitchPoints)?;
382 ModeSwitchPoint::new(name, &mode_switch_points, mode_group, context_port)
383 }
384
385 pub fn mode_switch_points(&self) -> impl Iterator<Item = ModeSwitchPoint> + Send + 'static {
387 self.element()
388 .get_sub_element(ElementName::ModeSwitchPoints)
389 .into_iter()
390 .flat_map(|mode_switch_points| mode_switch_points.sub_elements())
391 .filter_map(|elem| ModeSwitchPoint::try_from(elem).ok())
392 }
393}
394
395#[derive(Debug, Clone, PartialEq, Eq, Hash)]
399pub struct VariableAccess(Element);
400abstraction_element!(VariableAccess, VariableAccess);
401impl IdentifiableAbstractionElement for VariableAccess {}
402
403impl VariableAccess {
404 pub(crate) fn new(
405 name: &str,
406 parent: &Element,
407 data_element: &VariableDataPrototype,
408 context_port: &PortPrototype,
409 ) -> Result<Self, AutosarAbstractionError> {
410 let variable_access = parent.create_named_sub_element(ElementName::VariableAccess, name)?;
411 let variable_access = Self(variable_access);
412 variable_access.set_accessed_variable(data_element, context_port)?;
413
414 Ok(variable_access)
415 }
416
417 pub fn set_accessed_variable(
419 &self,
420 data_element: &VariableDataPrototype,
421 context_port: &PortPrototype,
422 ) -> Result<(), AutosarAbstractionError> {
423 let _ = self.element().remove_sub_element_kind(ElementName::AccessedVariable);
425 let accessed_variable = self.element().create_sub_element(ElementName::AccessedVariable)?;
426 let autosar_variable_iref = accessed_variable.create_sub_element(ElementName::AutosarVariableIref)?;
427
428 autosar_variable_iref
429 .create_sub_element(ElementName::TargetDataPrototypeRef)?
430 .set_reference_target(data_element.element())?;
431 autosar_variable_iref
432 .create_sub_element(ElementName::PortPrototypeRef)?
433 .set_reference_target(context_port.element())?;
434 Ok(())
435 }
436
437 #[must_use]
439 pub fn accessed_variable(&self) -> Option<(VariableDataPrototype, PortPrototype)> {
440 let accessed_variable = self.element().get_sub_element(ElementName::AccessedVariable)?;
441 let autosar_variable_iref = accessed_variable.get_sub_element(ElementName::AutosarVariableIref)?;
442 let data_prototype_ref = autosar_variable_iref.get_sub_element(ElementName::TargetDataPrototypeRef)?;
443 let port_prototype_ref = autosar_variable_iref.get_sub_element(ElementName::PortPrototypeRef)?;
444
445 let data_prototype = VariableDataPrototype::try_from(data_prototype_ref.get_reference_target().ok()?).ok()?;
446 let port_prototype = PortPrototype::try_from(port_prototype_ref.get_reference_target().ok()?).ok()?;
447
448 Some((data_prototype, port_prototype))
449 }
450
451 #[must_use]
453 pub fn runnable_entity(&self) -> Option<RunnableEntity> {
454 let parent = self.element().named_parent().ok()??;
455 RunnableEntity::try_from(parent).ok()
456 }
457}
458
459#[derive(Debug, Clone, PartialEq, Eq, Hash)]
463pub struct SynchronousServerCallPoint(Element);
464abstraction_element!(SynchronousServerCallPoint, SynchronousServerCallPoint);
465impl IdentifiableAbstractionElement for SynchronousServerCallPoint {}
466
467impl SynchronousServerCallPoint {
468 pub(crate) fn new(
469 name: &str,
470 parent: &Element,
471 client_server_operation: &ClientServerOperation,
472 context_r_port: &RPortPrototype,
473 ) -> Result<Self, AutosarAbstractionError> {
474 let synchronous_server_call_point =
475 parent.create_named_sub_element(ElementName::SynchronousServerCallPoint, name)?;
476 let synchronous_server_call_point = Self(synchronous_server_call_point);
477 synchronous_server_call_point.set_client_server_operation(client_server_operation, context_r_port)?;
478
479 Ok(synchronous_server_call_point)
480 }
481
482 pub fn set_client_server_operation(
484 &self,
485 client_server_operation: &ClientServerOperation,
486 context_r_port: &RPortPrototype,
487 ) -> Result<(), AutosarAbstractionError> {
488 let _ = self.element().remove_sub_element_kind(ElementName::OperationIref);
490 let operation_iref = self.element().create_sub_element(ElementName::OperationIref)?;
491
492 operation_iref
493 .create_sub_element(ElementName::TargetRequiredOperationRef)?
494 .set_reference_target(client_server_operation.element())?;
495 operation_iref
496 .create_sub_element(ElementName::ContextRPortRef)?
497 .set_reference_target(context_r_port.element())?;
498 Ok(())
499 }
500
501 #[must_use]
503 pub fn client_server_operation(&self) -> Option<(ClientServerOperation, RPortPrototype)> {
504 let operation_iref = self.element().get_sub_element(ElementName::OperationIref)?;
505 let required_operation_ref = operation_iref.get_sub_element(ElementName::TargetRequiredOperationRef)?;
506 let context_r_port_ref = operation_iref.get_sub_element(ElementName::ContextRPortRef)?;
507
508 let client_server_operation =
509 ClientServerOperation::try_from(required_operation_ref.get_reference_target().ok()?).ok()?;
510 let context_r_port = RPortPrototype::try_from(context_r_port_ref.get_reference_target().ok()?).ok()?;
511
512 Some((client_server_operation, context_r_port))
513 }
514
515 #[must_use]
517 pub fn runnable_entity(&self) -> Option<RunnableEntity> {
518 let parent = self.element().named_parent().ok()??;
519 RunnableEntity::try_from(parent).ok()
520 }
521}
522
523#[derive(Debug, Clone, PartialEq, Eq, Hash)]
527pub struct ModeAccessPoint(Element);
528abstraction_element!(ModeAccessPoint, ModeAccessPoint);
529
530impl IdentifiableAbstractionElement for ModeAccessPoint {
532 fn name(&self) -> Option<String> {
533 self.element()
534 .get_sub_element(ElementName::Ident)
535 .and_then(|elem| elem.item_name())
536 }
537
538 fn set_name(&self, name: &str) -> Result<(), AutosarAbstractionError> {
540 if let Some(ident_elem) = self.element().get_sub_element(ElementName::Ident) {
542 ident_elem.set_item_name(name)?;
543 } else {
544 self.element().create_named_sub_element(ElementName::Ident, name)?;
545 }
546 Ok(())
547 }
548}
549
550impl ModeAccessPoint {
551 pub(crate) fn new<T: Into<PortPrototype> + Clone>(
552 name: &str,
553 parent: &Element,
554 mode_group: &ModeGroup,
555 context_port: &T,
556 ) -> Result<Self, AutosarAbstractionError> {
557 let mode_access_point = parent.create_sub_element(ElementName::ModeAccessPoint)?;
558 let mode_access_point = Self(mode_access_point);
559 mode_access_point.set_name(name)?;
560 mode_access_point.set_mode_group(mode_group, context_port)?;
561
562 Ok(mode_access_point)
563 }
564
565 pub fn set_mode_group<T: Into<PortPrototype> + Clone>(
567 &self,
568 mode_group: &ModeGroup,
569 context_port: &T,
570 ) -> Result<(), AutosarAbstractionError> {
571 let context_port = context_port.clone().into();
572 let _ = self.element().remove_sub_element_kind(ElementName::ModeGroupIref);
574 let mode_group_iref = self.element().create_sub_element(ElementName::ModeGroupIref)?;
575
576 let context_port_elem = context_port.element();
577 match context_port {
578 PortPrototype::R(_) | PortPrototype::PR(_) => {
579 let r_ref_container =
580 mode_group_iref.create_sub_element(ElementName::RModeGroupInAtomicSwcInstanceRef)?;
581 r_ref_container
582 .create_sub_element(ElementName::ContextRPortRef)?
583 .set_reference_target(context_port_elem)?;
584 r_ref_container
585 .create_sub_element(ElementName::TargetModeGroupRef)?
586 .set_reference_target(mode_group.element())?;
587 }
588 PortPrototype::P(_) => {
589 let p_ref_container =
590 mode_group_iref.create_sub_element(ElementName::PModeGroupInAtomicSwcInstanceRef)?;
591 p_ref_container
592 .create_sub_element(ElementName::ContextPPortRef)?
593 .set_reference_target(context_port_elem)?;
594 p_ref_container
595 .create_sub_element(ElementName::TargetModeGroupRef)?
596 .set_reference_target(mode_group.element())?;
597 }
598 }
599
600 Ok(())
601 }
602
603 #[must_use]
605 pub fn mode_group(&self) -> Option<(ModeGroup, PortPrototype)> {
606 let mode_group_iref = self.element().get_sub_element(ElementName::ModeGroupIref)?;
607
608 if let Some(r_ref_container) = mode_group_iref.get_sub_element(ElementName::RModeGroupInAtomicSwcInstanceRef) {
610 let context_r_port = r_ref_container
611 .get_sub_element(ElementName::ContextRPortRef)?
612 .get_reference_target()
613 .ok()?;
614 let mode_group = r_ref_container
615 .get_sub_element(ElementName::TargetModeGroupRef)?
616 .get_reference_target()
617 .ok()?;
618 Some((
619 ModeGroup::try_from(mode_group).ok()?,
620 PortPrototype::try_from(context_r_port).ok()?,
621 ))
622 } else if let Some(p_ref_container) =
623 mode_group_iref.get_sub_element(ElementName::PModeGroupInAtomicSwcInstanceRef)
624 {
625 let context_p_port = p_ref_container
626 .get_sub_element(ElementName::ContextPPortRef)?
627 .get_reference_target()
628 .ok()?;
629 let mode_group = p_ref_container
630 .get_sub_element(ElementName::TargetModeGroupRef)?
631 .get_reference_target()
632 .ok()?;
633 Some((
634 ModeGroup::try_from(mode_group).ok()?,
635 PortPrototype::try_from(context_p_port).ok()?,
636 ))
637 } else {
638 None
639 }
640 }
641
642 #[must_use]
644 pub fn runnable_entity(&self) -> Option<RunnableEntity> {
645 let parent = self.element().named_parent().ok()??;
646 RunnableEntity::try_from(parent).ok()
647 }
648}
649
650#[derive(Debug, Clone, PartialEq, Eq, Hash)]
654pub struct ModeSwitchPoint(Element);
655abstraction_element!(ModeSwitchPoint, ModeSwitchPoint);
656impl IdentifiableAbstractionElement for ModeSwitchPoint {}
657
658impl ModeSwitchPoint {
659 pub(crate) fn new<T: Into<PortPrototype> + Clone>(
660 name: &str,
661 parent: &Element,
662 mode_group: &ModeGroup,
663 context_port: &T,
664 ) -> Result<Self, AutosarAbstractionError> {
665 let mode_switch_point = parent.create_named_sub_element(ElementName::ModeSwitchPoint, name)?;
666 let mode_switch_point = Self(mode_switch_point);
667 mode_switch_point.set_mode_group(mode_group, context_port)?;
668
669 Ok(mode_switch_point)
670 }
671
672 pub fn set_mode_group<T: Into<PortPrototype> + Clone>(
674 &self,
675 mode_group: &ModeGroup,
676 context_port: &T,
677 ) -> Result<(), AutosarAbstractionError> {
678 let context_port = context_port.clone().into();
679 if matches!(context_port, PortPrototype::R(_)) {
680 return Err(AutosarAbstractionError::InvalidParameter(
681 "ModeSwitchPoint context_port cannot be an R port".to_string(),
682 ));
683 }
684
685 let _ = self.element().remove_sub_element_kind(ElementName::ModeGroupIref);
687 let mode_group_iref = self.element().create_sub_element(ElementName::ModeGroupIref)?;
688
689 mode_group_iref
690 .create_sub_element(ElementName::TargetModeGroupRef)?
691 .set_reference_target(mode_group.element())?;
692 mode_group_iref
693 .create_sub_element(ElementName::ContextPPortRef)?
694 .set_reference_target(context_port.element())?;
695
696 Ok(())
697 }
698
699 #[must_use]
701 pub fn mode_group(&self) -> Option<(ModeGroup, PortPrototype)> {
702 let mode_group_iref = self.element().get_sub_element(ElementName::ModeGroupIref)?;
703 let mode_group = mode_group_iref
704 .get_sub_element(ElementName::TargetModeGroupRef)?
705 .get_reference_target()
706 .ok()?;
707 let context_port = mode_group_iref
708 .get_sub_element(ElementName::ContextPPortRef)?
709 .get_reference_target()
710 .ok()?;
711
712 let mode_declaration = ModeGroup::try_from(mode_group).ok()?;
713 let context_port = PortPrototype::try_from(context_port).ok()?;
714
715 Some((mode_declaration, context_port))
716 }
717
718 #[must_use]
720 pub fn runnable_entity(&self) -> Option<RunnableEntity> {
721 let parent = self.element().named_parent().ok()??;
722 RunnableEntity::try_from(parent).ok()
723 }
724}
725
726#[cfg(test)]
729mod test {
730 use super::*;
731 use crate::{
732 AbstractionElement, AutosarModelAbstraction,
733 datatype::ApplicationPrimitiveCategory,
734 software_component::{AbstractRTEEvent, AbstractSwComponentType, AtomicSwComponentType},
735 };
736 use autosar_data::{AutosarVersion, EnumItem};
737
738 #[test]
739 fn swc_internal_behavior() {
740 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
741 let package = model.get_or_create_package("/package").unwrap();
742
743 let client_server_interface = package.create_client_server_interface("ClientServerInterface").unwrap();
745 let operation = client_server_interface.create_operation("TestOperation").unwrap();
746
747 let app_swc = package
749 .create_application_sw_component_type("AppSwComponentType")
750 .unwrap();
751 let p_port = app_swc.create_p_port("p_port", &client_server_interface).unwrap();
752 let swc_internal_behavior = app_swc
753 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
754 .unwrap();
755 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
756 assert_eq!(swc_internal_behavior.sw_component_type().unwrap(), app_swc.into());
757
758 let runnable1 = swc_internal_behavior.create_runnable_entity("Runnable1").unwrap();
760 assert_eq!(runnable1.swc_internal_behavior().unwrap(), swc_internal_behavior);
761 let runnable2 = swc_internal_behavior.create_runnable_entity("Runnable2").unwrap();
762 assert_eq!(swc_internal_behavior.runnable_entities().count(), 2);
763
764 let init_event = swc_internal_behavior
766 .create_init_event("InitEvent", &runnable1)
767 .unwrap();
768 assert_eq!(init_event.runnable_entity().unwrap(), runnable1);
769
770 let op_invoked_event = swc_internal_behavior
772 .create_operation_invoked_event("OpInvokedEvent", &runnable1, &operation, &p_port)
773 .unwrap();
774 let (op_invoked_event_operation, context_p_port) = op_invoked_event.client_server_operation().unwrap();
775 assert_eq!(op_invoked_event_operation, operation);
776 assert_eq!(context_p_port, p_port);
777 assert_eq!(op_invoked_event.runnable_entity().unwrap(), runnable1);
778
779 let background_event = swc_internal_behavior
781 .create_background_event("BackgroundEvent", &runnable1)
782 .unwrap();
783 assert_eq!(background_event.runnable_entity().unwrap(), runnable1);
784
785 let os_task_execution_event = swc_internal_behavior
787 .create_os_task_execution_event("OsTaskExecutionEvent", &runnable1)
788 .unwrap();
789 assert_eq!(os_task_execution_event.runnable_entity().unwrap(), runnable1);
790
791 let timing_event = swc_internal_behavior
793 .create_timing_event("TimingEvent", &runnable2, 0.1)
794 .unwrap();
795 assert_eq!(timing_event.period().unwrap(), 0.1);
796 assert_eq!(timing_event.runnable_entity().unwrap(), runnable2);
797 assert_eq!(timing_event.swc_internal_behavior().unwrap(), swc_internal_behavior);
798
799 assert_eq!(swc_internal_behavior.events().count(), 5);
801 let mut events_iter = swc_internal_behavior.events();
803 assert_eq!(events_iter.next().unwrap().element(), init_event.element());
804 assert_eq!(events_iter.next().unwrap().element(), op_invoked_event.element());
805 assert_eq!(events_iter.next().unwrap().element(), background_event.element());
806 assert_eq!(events_iter.next().unwrap().element(), os_task_execution_event.element());
807 assert_eq!(events_iter.next().unwrap().element(), timing_event.element());
808
809 assert_eq!(runnable1.events().len(), 4);
811 assert_eq!(runnable2.events().len(), 1);
813
814 let data_type_mapping_set = package.create_data_type_mapping_set("MappingSet").unwrap();
816 swc_internal_behavior
817 .add_data_type_mapping_set(&data_type_mapping_set)
818 .unwrap();
819 assert_eq!(swc_internal_behavior.data_type_mapping_sets().count(), 1);
820 }
821
822 #[test]
823 fn mode_switch_event() {
824 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
825 let package = model.get_or_create_package("/package").unwrap();
826
827 let app_swc = package
829 .create_application_sw_component_type("AppSwComponentType")
830 .unwrap();
831 let swc_internal_behavior = app_swc
832 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
833 .unwrap();
834 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
835 assert_eq!(
836 swc_internal_behavior.sw_component_type().unwrap(),
837 app_swc.clone().into()
838 );
839
840 let mode_declaration_group = package
842 .create_mode_declaration_group("ModeDeclarationGroup", None)
843 .unwrap();
844 let mode_declaration_1 = mode_declaration_group
845 .create_mode_declaration("ModeDeclaration1")
846 .unwrap();
847 let mode_declaration_2 = mode_declaration_group
848 .create_mode_declaration("ModeDeclaration2")
849 .unwrap();
850 let mode_switch_interface = package.create_mode_switch_interface("ModeSwitchInterface").unwrap();
851 let r_port = app_swc.create_r_port("r_port", &mode_switch_interface).unwrap();
852
853 let mode_declaration_group2 = package
854 .create_mode_declaration_group("ModeDeclarationGroup2", None)
855 .unwrap();
856 let mode_declaration_g2 = mode_declaration_group2
857 .create_mode_declaration("ModeDeclaratio_g2")
858 .unwrap();
859
860 let client_server_interface = package.create_client_server_interface("ClientServerInterface").unwrap();
862 let bad_port = app_swc.create_r_port("bad_port", &client_server_interface).unwrap();
863
864 let runnable = swc_internal_behavior.create_runnable_entity("Runnable1").unwrap();
866 assert_eq!(runnable.swc_internal_behavior().unwrap(), swc_internal_behavior);
867
868 let result = swc_internal_behavior.create_mode_switch_event(
870 "ModeSwitchEvent",
871 &runnable,
872 ModeActivationKind::OnEntry,
873 &bad_port,
874 &mode_declaration_g2,
875 None,
876 );
877 assert!(result.is_err());
878
879 let result = swc_internal_behavior.create_mode_switch_event(
881 "ModeSwitchEvent",
882 &runnable,
883 ModeActivationKind::OnEntry,
884 &r_port,
885 &mode_declaration_1,
886 Some(&mode_declaration_2),
887 );
888 assert!(result.is_err());
889
890 mode_switch_interface
892 .create_mode_group("mode_group", &mode_declaration_group)
893 .unwrap();
894
895 let result = swc_internal_behavior.create_mode_switch_event(
897 "ModeSwitchEvent",
898 &runnable,
899 ModeActivationKind::OnEntry,
900 &r_port,
901 &mode_declaration_g2,
902 None,
903 );
904 assert!(result.is_err());
905
906 let mode_switch_event = swc_internal_behavior
908 .create_mode_switch_event(
909 "ModeSwitchEvent",
910 &runnable,
911 ModeActivationKind::OnEntry,
912 &r_port,
913 &mode_declaration_1,
914 Some(&mode_declaration_2),
915 )
916 .unwrap();
917 assert_eq!(mode_switch_event.runnable_entity().unwrap(), runnable);
918
919 assert_eq!(runnable.events().len(), 1);
920
921 let (mode_decls, context_port) = mode_switch_event.mode_declarations().unwrap();
922 assert_eq!(context_port, r_port.into());
923 assert_eq!(mode_decls.len(), 2);
924 assert_eq!(mode_decls[0], mode_declaration_1);
925 assert_eq!(mode_decls[1], mode_declaration_2);
926
927 mode_switch_event
929 .set_mode_activation_kind(ModeActivationKind::OnEntry)
930 .unwrap();
931 assert_eq!(
932 mode_switch_event.mode_activation_kind().unwrap(),
933 ModeActivationKind::OnEntry
934 );
935 mode_switch_event
936 .set_mode_activation_kind(ModeActivationKind::OnExit)
937 .unwrap();
938 assert_eq!(
939 mode_switch_event.mode_activation_kind().unwrap(),
940 ModeActivationKind::OnExit
941 );
942 mode_switch_event
943 .set_mode_activation_kind(ModeActivationKind::OnTransition)
944 .unwrap();
945 assert_eq!(
946 mode_switch_event.mode_activation_kind().unwrap(),
947 ModeActivationKind::OnTransition
948 );
949
950 let activation_kind = ModeActivationKind::try_from(EnumItem::Opaque);
952 assert!(activation_kind.is_err());
953 }
954
955 #[test]
956 fn data_received_event() {
957 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
958 let package = model.get_or_create_package("/package").unwrap();
959
960 let sender_receiver_interface = package
962 .create_sender_receiver_interface("SenderReceiverInterface")
963 .unwrap();
964 let app_data_type = package
965 .create_application_primitive_data_type("uint32", ApplicationPrimitiveCategory::Value, None, None, None)
966 .unwrap();
967 let variable_data_prototype = sender_receiver_interface
968 .create_data_element("data", &app_data_type)
969 .unwrap();
970
971 let app_swc = package
973 .create_application_sw_component_type("AppSwComponentType")
974 .unwrap();
975 let r_port = app_swc.create_r_port("r_port", &sender_receiver_interface).unwrap();
976 let swc_internal_behavior = app_swc
977 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
978 .unwrap();
979 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
980 assert_eq!(
981 swc_internal_behavior.sw_component_type().unwrap(),
982 app_swc.clone().into()
983 );
984
985 let p_port = app_swc.create_p_port("p_port", &sender_receiver_interface).unwrap();
987
988 let client_server_interface = package.create_client_server_interface("ClientServerInterface").unwrap();
990 let cs_port = app_swc.create_r_port("cs_port", &client_server_interface).unwrap();
991
992 let runnable = swc_internal_behavior.create_runnable_entity("Runnable1").unwrap();
994 assert_eq!(runnable.swc_internal_behavior().unwrap(), swc_internal_behavior);
995
996 let result = swc_internal_behavior.create_data_received_event(
998 "DataReceivedEvent",
999 &runnable,
1000 &variable_data_prototype,
1001 &cs_port,
1002 );
1003 assert!(result.is_err());
1004
1005 let result = swc_internal_behavior.create_data_received_event(
1007 "DataReceivedEvent",
1008 &runnable,
1009 &variable_data_prototype,
1010 &p_port,
1011 );
1012 assert!(result.is_err());
1013
1014 let data_received_event = swc_internal_behavior
1016 .create_data_received_event("DataReceivedEvent", &runnable, &variable_data_prototype, &r_port)
1017 .unwrap();
1018 assert_eq!(data_received_event.runnable_entity().unwrap(), runnable);
1019
1020 let (data_element, context_port) = data_received_event.variable_data_prototype().unwrap();
1021 assert_eq!(data_element, variable_data_prototype);
1022 assert_eq!(context_port, r_port.into());
1023 assert_eq!(data_received_event.runnable_entity().unwrap(), runnable);
1024 }
1025
1026 #[test]
1027 fn variable_access() {
1028 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1029 let package = model.get_or_create_package("/package").unwrap();
1030
1031 let sender_receiver_interface = package
1033 .create_sender_receiver_interface("SenderReceiverInterface")
1034 .unwrap();
1035 let app_data_type = package
1036 .create_application_primitive_data_type("uint32", ApplicationPrimitiveCategory::Value, None, None, None)
1037 .unwrap();
1038 let variable_data_prototype = sender_receiver_interface
1039 .create_data_element("data", &app_data_type)
1040 .unwrap();
1041
1042 let app_swc = package
1044 .create_application_sw_component_type("AppSwComponentType")
1045 .unwrap();
1046 let r_port = app_swc.create_r_port("r_port", &sender_receiver_interface).unwrap();
1047 let p_port = app_swc.create_p_port("p_port", &sender_receiver_interface).unwrap();
1048 let swc_internal_behavior = app_swc
1049 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
1050 .unwrap();
1051 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
1052 assert_eq!(
1053 swc_internal_behavior.sw_component_type().unwrap(),
1054 app_swc.clone().into()
1055 );
1056
1057 let runnable = swc_internal_behavior.create_runnable_entity("Runnable").unwrap();
1059 assert_eq!(runnable.swc_internal_behavior().unwrap(), swc_internal_behavior);
1060
1061 let variable_access = runnable
1063 .create_data_read_access("DataReadAccess", &variable_data_prototype, &r_port)
1064 .unwrap();
1065 assert_eq!(variable_access.runnable_entity().unwrap(), runnable);
1066 assert_eq!(variable_access.accessed_variable().unwrap().0, variable_data_prototype);
1067 assert_eq!(runnable.data_read_accesses().count(), 1);
1068
1069 let variable_access = runnable
1071 .create_data_write_access("DataWriteAccess", &variable_data_prototype, &p_port)
1072 .unwrap();
1073 assert_eq!(variable_access.runnable_entity().unwrap(), runnable);
1074 assert_eq!(variable_access.accessed_variable().unwrap().0, variable_data_prototype);
1075 assert_eq!(runnable.data_write_accesses().count(), 1);
1076
1077 let variable_access = runnable
1079 .create_data_send_point("DataSendPoint", &variable_data_prototype, &p_port)
1080 .unwrap();
1081 assert_eq!(variable_access.runnable_entity().unwrap(), runnable);
1082 assert_eq!(variable_access.accessed_variable().unwrap().0, variable_data_prototype);
1083 assert_eq!(runnable.data_send_points().count(), 1);
1084
1085 let variable_access = runnable
1087 .create_data_receive_point_by_argument("DataReceivePointByArgument", &variable_data_prototype, &r_port)
1088 .unwrap();
1089 assert_eq!(variable_access.runnable_entity().unwrap(), runnable);
1090 assert_eq!(variable_access.accessed_variable().unwrap().0, variable_data_prototype);
1091 assert_eq!(runnable.data_receive_points_by_argument().count(), 1);
1092
1093 let variable_access = runnable
1095 .create_data_receive_point_by_value("DataReceivePointByValue", &variable_data_prototype, &r_port)
1096 .unwrap();
1097 assert_eq!(variable_access.runnable_entity().unwrap(), runnable);
1098 assert_eq!(variable_access.accessed_variable().unwrap().0, variable_data_prototype);
1099 assert_eq!(runnable.data_receive_points_by_value().count(), 1);
1100 }
1101
1102 #[test]
1103 fn synchronous_server_call_point() {
1104 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1105 let package = model.get_or_create_package("/package").unwrap();
1106
1107 let client_server_interface = package.create_client_server_interface("ClientServerInterface").unwrap();
1109 let operation = client_server_interface.create_operation("TestOperation").unwrap();
1110
1111 let app_swc = package
1113 .create_application_sw_component_type("AppSwComponentType")
1114 .unwrap();
1115 let r_port = app_swc.create_r_port("r_port", &client_server_interface).unwrap();
1116 let swc_internal_behavior = app_swc
1117 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
1118 .unwrap();
1119 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
1120 assert_eq!(
1121 swc_internal_behavior.sw_component_type().unwrap(),
1122 app_swc.clone().into()
1123 );
1124
1125 let runnable = swc_internal_behavior.create_runnable_entity("Runnable1").unwrap();
1127 assert_eq!(runnable.swc_internal_behavior().unwrap(), swc_internal_behavior);
1128
1129 let synchronous_server_call_point = runnable
1131 .create_synchronous_server_call_point("SynchronousServerCallPoint", &operation, &r_port)
1132 .unwrap();
1133 assert_eq!(synchronous_server_call_point.runnable_entity().unwrap(), runnable);
1134 assert_eq!(
1135 synchronous_server_call_point.client_server_operation().unwrap().0,
1136 operation
1137 );
1138 assert_eq!(runnable.synchronous_server_call_points().count(), 1);
1139 }
1140
1141 #[test]
1142 fn mode_access_point() {
1143 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1144 let package = model.get_or_create_package("/package").unwrap();
1145
1146 let mode_declaration_group = package
1148 .create_mode_declaration_group("ModeDeclarationGroup", None)
1149 .unwrap();
1150 let mode_switch_interface = package.create_mode_switch_interface("ModeSwitchInterface").unwrap();
1152 let mode_group = mode_switch_interface
1154 .create_mode_group("mode_group", &mode_declaration_group)
1155 .unwrap();
1156
1157 let app_swc = package
1159 .create_application_sw_component_type("AppSwComponentType")
1160 .unwrap();
1161 let r_port = app_swc.create_r_port("r_port", &mode_switch_interface).unwrap();
1162 let p_port = app_swc.create_p_port("p_port", &mode_switch_interface).unwrap();
1163 let swc_internal_behavior = app_swc
1164 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
1165 .unwrap();
1166 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
1167 assert_eq!(
1168 swc_internal_behavior.sw_component_type().unwrap(),
1169 app_swc.clone().into()
1170 );
1171
1172 let runnable = swc_internal_behavior.create_runnable_entity("Runnable1").unwrap();
1174 assert_eq!(runnable.swc_internal_behavior().unwrap(), swc_internal_behavior);
1175
1176 let mode_access_point_r = runnable
1178 .create_mode_access_point("ModeAccessPoint", &mode_group, &r_port)
1179 .unwrap();
1180 assert_eq!(mode_access_point_r.name(), Some("ModeAccessPoint".to_string()));
1181 let mode_access_point_p = runnable
1182 .create_mode_access_point("ModeAccessPointP", &mode_group, &p_port)
1183 .unwrap();
1184 assert_eq!(mode_access_point_p.name(), Some("ModeAccessPointP".to_string()));
1185 assert_eq!(mode_access_point_r.runnable_entity().unwrap(), runnable);
1186 assert_eq!(mode_access_point_p.runnable_entity().unwrap(), runnable);
1187 assert_eq!(mode_access_point_r.mode_group().unwrap().0, mode_group);
1188 assert_eq!(mode_access_point_p.mode_group().unwrap().0, mode_group);
1189 assert_eq!(mode_access_point_r.mode_group().unwrap().1, r_port.into());
1190 assert_eq!(mode_access_point_p.mode_group().unwrap().1, p_port.into());
1191 assert_eq!(runnable.mode_access_points().count(), 2);
1192 }
1193
1194 #[test]
1195 fn test_mode_switch_point() {
1196 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1197 let package = model.get_or_create_package("/package").unwrap();
1198
1199 let mode_declaration_group = package
1201 .create_mode_declaration_group("ModeDeclarationGroup", None)
1202 .unwrap();
1203 let mode_switch_interface = package.create_mode_switch_interface("ModeSwitchInterface").unwrap();
1205 let mode_group = mode_switch_interface
1207 .create_mode_group("mode_group", &mode_declaration_group)
1208 .unwrap();
1209
1210 let app_swc = package
1212 .create_application_sw_component_type("AppSwComponentType")
1213 .unwrap();
1214 let p_port = app_swc.create_p_port("p_port", &mode_switch_interface).unwrap();
1215 let swc_internal_behavior = app_swc
1216 .create_swc_internal_behavior("AppSwComponentType_InternalBehavior")
1217 .unwrap();
1218 assert_eq!(app_swc.swc_internal_behaviors().count(), 1);
1219 assert_eq!(
1220 swc_internal_behavior.sw_component_type().unwrap(),
1221 app_swc.clone().into()
1222 );
1223
1224 let runnable = swc_internal_behavior.create_runnable_entity("Runnable1").unwrap();
1226 assert_eq!(runnable.swc_internal_behavior().unwrap(), swc_internal_behavior);
1227
1228 let mode_switch_point = runnable
1230 .create_mode_switch_point("ModeSwitchPoint", &mode_group, &p_port)
1231 .unwrap();
1232 assert_eq!(mode_switch_point.runnable_entity().unwrap(), runnable);
1233 assert_eq!(mode_switch_point.mode_group().unwrap().0, mode_group);
1234 assert_eq!(mode_switch_point.mode_group().unwrap().1, p_port.into());
1235 assert_eq!(runnable.mode_switch_points().count(), 1);
1236 }
1237}