autosar_data_abstraction/software_component/internal_behavior/
rte_event.rs

1use crate::{
2    AbstractionElement, AutosarAbstractionError, Element, IdentifiableAbstractionElement, abstraction_element,
3    software_component::{
4        ClientServerOperation, ModeDeclaration, PPortPrototype, PortInterface, PortPrototype, RunnableEntity,
5        SwcInternalBehavior, VariableDataPrototype,
6    },
7};
8use autosar_data::{ElementName, EnumItem};
9
10//##################################################################
11
12/// A `AbstractRTEEvent` is an event that triggers a `RunnableEntity` in the RTE
13///
14/// All different kinds of triggering event share the common trait `AbstractRTEEvent`
15pub trait AbstractRTEEvent: AbstractionElement {
16    /// Set the `RunnableEntity` that is triggered by the `TimingEvent`
17    fn set_runnable_entity(&self, runnable_entity: &RunnableEntity) -> Result<(), AutosarAbstractionError> {
18        self.element()
19            .get_or_create_sub_element(ElementName::StartOnEventRef)?
20            .set_reference_target(runnable_entity.element())?;
21        Ok(())
22    }
23
24    /// Get the `RunnableEntity` that is triggered by the `TimingEvent`
25    fn runnable_entity(&self) -> Option<RunnableEntity> {
26        let runnable_elem = self
27            .element()
28            .get_sub_element(ElementName::StartOnEventRef)?
29            .get_reference_target()
30            .ok()?;
31        RunnableEntity::try_from(runnable_elem).ok()
32    }
33
34    /// Get the `SwcInternalBehavior` that contains the event
35    fn swc_internal_behavior(&self) -> Option<SwcInternalBehavior> {
36        let parent = self.element().named_parent().ok()??;
37        SwcInternalBehavior::try_from(parent).ok()
38    }
39}
40
41//##################################################################
42
43/// A `TimingEvent` is a subclass of `RTEEvent` which triggers a `RunnableEntity` periodically
44#[derive(Debug, Clone, PartialEq, Eq, Hash)]
45pub struct TimingEvent(Element);
46abstraction_element!(TimingEvent, TimingEvent);
47impl IdentifiableAbstractionElement for TimingEvent {}
48impl AbstractRTEEvent for TimingEvent {}
49
50impl TimingEvent {
51    pub(crate) fn new(
52        name: &str,
53        parent: &Element,
54        runnable: &RunnableEntity,
55        period: f64,
56    ) -> Result<Self, AutosarAbstractionError> {
57        let timing_event = parent.create_named_sub_element(ElementName::TimingEvent, name)?;
58        let timing_event = Self(timing_event);
59        timing_event.set_runnable_entity(runnable)?;
60        timing_event.set_period(period)?;
61
62        Ok(timing_event)
63    }
64
65    /// Set the period of the `TimingEvent`
66    pub fn set_period(&self, period: f64) -> Result<(), AutosarAbstractionError> {
67        self.element()
68            .get_or_create_sub_element(ElementName::Period)?
69            .set_character_data(period)?;
70        Ok(())
71    }
72
73    /// Get the period of the `TimingEvent`
74    #[must_use]
75    pub fn period(&self) -> Option<f64> {
76        self.element()
77            .get_sub_element(ElementName::Period)?
78            .character_data()?
79            .parse_float()
80    }
81}
82
83//##################################################################
84
85/// an asynchronous server call completed
86#[derive(Debug, Clone, PartialEq, Eq, Hash)]
87pub struct AsynchronousServerCallReturnsEvent(Element);
88abstraction_element!(AsynchronousServerCallReturnsEvent, AsynchronousServerCallReturnsEvent);
89impl IdentifiableAbstractionElement for AsynchronousServerCallReturnsEvent {}
90impl AbstractRTEEvent for AsynchronousServerCallReturnsEvent {}
91
92//##################################################################
93
94/// starts a runnable for background processing at low priority
95#[derive(Debug, Clone, PartialEq, Eq, Hash)]
96pub struct BackgroundEvent(Element);
97abstraction_element!(BackgroundEvent, BackgroundEvent);
98impl IdentifiableAbstractionElement for BackgroundEvent {}
99impl AbstractRTEEvent for BackgroundEvent {}
100
101impl BackgroundEvent {
102    pub(crate) fn new(
103        name: &str,
104        parent: &Element,
105        runnable: &RunnableEntity,
106    ) -> Result<Self, AutosarAbstractionError> {
107        let background_event = parent.create_named_sub_element(ElementName::BackgroundEvent, name)?;
108        let background_event = Self(background_event);
109        background_event.set_runnable_entity(runnable)?;
110
111        Ok(background_event)
112    }
113}
114
115//##################################################################
116
117/// raised in response to an error during data reception
118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
119pub struct DataReceiveErrorEvent(Element);
120abstraction_element!(DataReceiveErrorEvent, DataReceiveErrorEvent);
121impl IdentifiableAbstractionElement for DataReceiveErrorEvent {}
122impl AbstractRTEEvent for DataReceiveErrorEvent {}
123
124//##################################################################
125
126/// raised when data is received
127#[derive(Debug, Clone, PartialEq, Eq, Hash)]
128pub struct DataReceivedEvent(Element);
129abstraction_element!(DataReceivedEvent, DataReceivedEvent);
130impl IdentifiableAbstractionElement for DataReceivedEvent {}
131impl AbstractRTEEvent for DataReceivedEvent {}
132
133impl DataReceivedEvent {
134    pub(crate) fn new<T: Into<PortPrototype> + Clone>(
135        name: &str,
136        parent: &Element,
137        runnable: &RunnableEntity,
138        variable_data_prototype: &VariableDataPrototype,
139        context_port: &T,
140    ) -> Result<Self, AutosarAbstractionError> {
141        let data_received_event = parent.create_named_sub_element(ElementName::DataReceivedEvent, name)?;
142        let data_received_event = Self(data_received_event);
143        data_received_event.set_runnable_entity(runnable)?;
144
145        let result = data_received_event.set_variable_data_prototype(variable_data_prototype, context_port);
146        if let Err(err) = result {
147            // this operation could fail if bad parameters are provided; in this case we remove the event
148            parent.remove_sub_element(data_received_event.0)?;
149            return Err(err);
150        }
151
152        Ok(data_received_event)
153    }
154
155    /// Set the `VariableDataPrototype` that triggers the `DataReceivedEvent`
156    pub fn set_variable_data_prototype<T: Into<PortPrototype> + Clone>(
157        &self,
158        variable_data_prototype: &VariableDataPrototype,
159        context_port: &T,
160    ) -> Result<(), AutosarAbstractionError> {
161        let context_port = context_port.clone().into();
162        // reject P-Ports. It's not clear if PRPortPrototypes are allowed here, so let's not reject them for now
163        if matches!(context_port, PortPrototype::P(_)) {
164            return Err(AutosarAbstractionError::InvalidParameter(
165                "A DataReceivedEvent must refer to a port using an RPortPrototype".to_string(),
166            ));
167        }
168        // the port must be a sender-receiver port
169        let Some(PortInterface::SenderReceiverInterface(sr_interface)) = context_port.port_interface() else {
170            return Err(AutosarAbstractionError::InvalidParameter(
171                "A DataReceivedEvent must refer to a port using a SenderReceiverInterface".to_string(),
172            ));
173        };
174        // the variable data prototype must be part of the sender-receiver interface
175        if sr_interface != variable_data_prototype.interface()? {
176            return Err(AutosarAbstractionError::InvalidParameter(format!(
177                "VariableDataPrototype {} is not part of SenderReceiverInterface {}",
178                variable_data_prototype.name().as_deref().unwrap_or("(invalid)"),
179                sr_interface.name().as_deref().unwrap_or("(invalid)")
180            )));
181        }
182
183        // all ok, create the reference
184        let data_iref = self.element().get_or_create_sub_element(ElementName::DataIref)?;
185        data_iref
186            .get_or_create_sub_element(ElementName::ContextRPortRef)?
187            .set_reference_target(context_port.element())?;
188        data_iref
189            .get_or_create_sub_element(ElementName::TargetDataElementRef)?
190            .set_reference_target(variable_data_prototype.element())?;
191
192        Ok(())
193    }
194
195    /// Get the `VariableDataPrototype` that triggers the `DataReceivedEvent`
196    #[must_use]
197    pub fn variable_data_prototype(&self) -> Option<(VariableDataPrototype, PortPrototype)> {
198        let data_iref = self.element().get_sub_element(ElementName::DataIref)?;
199        let variable_data_prototype_elem = data_iref
200            .get_sub_element(ElementName::TargetDataElementRef)?
201            .get_reference_target()
202            .ok()?;
203        let context_port_elem = data_iref
204            .get_sub_element(ElementName::ContextRPortRef)?
205            .get_reference_target()
206            .ok()?;
207        let variable_data_prototype = VariableDataPrototype::try_from(variable_data_prototype_elem).ok()?;
208        let context_port = PortPrototype::try_from(context_port_elem).ok()?;
209        Some((variable_data_prototype, context_port))
210    }
211}
212
213//##################################################################
214
215/// raised when data has been sent
216#[derive(Debug, Clone, PartialEq, Eq, Hash)]
217pub struct DataSendCompletedEvent(Element);
218abstraction_element!(DataSendCompletedEvent, DataSendCompletedEvent);
219impl IdentifiableAbstractionElement for DataSendCompletedEvent {}
220impl AbstractRTEEvent for DataSendCompletedEvent {}
221
222//##################################################################
223
224/// raised when an implicit write access was successful or an error occurred
225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
226pub struct DataWriteCompletedEvent(Element);
227abstraction_element!(DataWriteCompletedEvent, DataWriteCompletedEvent);
228impl IdentifiableAbstractionElement for DataWriteCompletedEvent {}
229impl AbstractRTEEvent for DataWriteCompletedEvent {}
230
231//##################################################################
232
233/// raised when the referenced trigger occurred
234#[derive(Debug, Clone, PartialEq, Eq, Hash)]
235pub struct ExternalTriggerOccurredEvent(Element);
236abstraction_element!(ExternalTriggerOccurredEvent, ExternalTriggerOccurredEvent);
237impl IdentifiableAbstractionElement for ExternalTriggerOccurredEvent {}
238impl AbstractRTEEvent for ExternalTriggerOccurredEvent {}
239
240//##################################################################
241
242/// triggered once after the RTE has been started
243#[derive(Debug, Clone, PartialEq, Eq, Hash)]
244pub struct InitEvent(Element);
245abstraction_element!(InitEvent, InitEvent);
246impl IdentifiableAbstractionElement for InitEvent {}
247impl AbstractRTEEvent for InitEvent {}
248
249impl InitEvent {
250    pub(crate) fn new(
251        name: &str,
252        parent: &Element,
253        runnable: &RunnableEntity,
254    ) -> Result<Self, AutosarAbstractionError> {
255        let init_event = parent.create_named_sub_element(ElementName::InitEvent, name)?;
256        let init_event = Self(init_event);
257        init_event.set_runnable_entity(runnable)?;
258
259        Ok(init_event)
260    }
261}
262
263//##################################################################
264
265/// The referenced `InternalTriggeringPoint` raises this `InternalTriggerOccurredEvent`
266#[derive(Debug, Clone, PartialEq, Eq, Hash)]
267pub struct InternalTriggerOccurredEvent(Element);
268abstraction_element!(InternalTriggerOccurredEvent, InternalTriggerOccurredEvent);
269impl IdentifiableAbstractionElement for InternalTriggerOccurredEvent {}
270impl AbstractRTEEvent for InternalTriggerOccurredEvent {}
271
272//##################################################################
273
274/// raised when the referenced `ModeSwitchPoint` has been acknowledged
275#[derive(Debug, Clone, PartialEq, Eq, Hash)]
276pub struct ModeSwitchedAckEvent(Element);
277abstraction_element!(ModeSwitchedAckEvent, ModeSwitchedAckEvent);
278impl IdentifiableAbstractionElement for ModeSwitchedAckEvent {}
279impl AbstractRTEEvent for ModeSwitchedAckEvent {}
280
281//##################################################################
282
283/// raised in order to run the server runnable of a `ClientServerOperation`
284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
285pub struct OperationInvokedEvent(Element);
286abstraction_element!(OperationInvokedEvent, OperationInvokedEvent);
287impl IdentifiableAbstractionElement for OperationInvokedEvent {}
288impl AbstractRTEEvent for OperationInvokedEvent {}
289
290impl OperationInvokedEvent {
291    pub(crate) fn new(
292        name: &str,
293        parent: &Element,
294        runnable: &RunnableEntity,
295        client_server_operation: &ClientServerOperation,
296        context_p_port: &PPortPrototype,
297    ) -> Result<Self, AutosarAbstractionError> {
298        let operation_invoked_event = parent.create_named_sub_element(ElementName::OperationInvokedEvent, name)?;
299        let operation_invoked_event = Self(operation_invoked_event);
300        operation_invoked_event.set_runnable_entity(runnable)?;
301        operation_invoked_event.set_client_server_operation(client_server_operation, context_p_port)?;
302
303        Ok(operation_invoked_event)
304    }
305
306    /// Set the `ClientServerOperation` that is triggers the `OperationInvokedEvent`
307    pub fn set_client_server_operation(
308        &self,
309        client_server_operation: &ClientServerOperation,
310        context_p_port: &PPortPrototype,
311    ) -> Result<(), AutosarAbstractionError> {
312        // Todo: verify that the port belongs to the containing swc
313
314        let op_iref = self.element().get_or_create_sub_element(ElementName::OperationIref)?;
315        op_iref
316            .get_or_create_sub_element(ElementName::TargetProvidedOperationRef)?
317            .set_reference_target(client_server_operation.element())?;
318        op_iref
319            .get_or_create_sub_element(ElementName::ContextPPortRef)?
320            .set_reference_target(context_p_port.element())?;
321        Ok(())
322    }
323
324    /// Get the `ClientServerOperation` that triggers the `OperationInvokedEvent`
325    #[must_use]
326    pub fn client_server_operation(&self) -> Option<(ClientServerOperation, PPortPrototype)> {
327        let op_iref = self.element().get_sub_element(ElementName::OperationIref)?;
328        let operation_elem = op_iref
329            .get_sub_element(ElementName::TargetProvidedOperationRef)?
330            .get_reference_target()
331            .ok()?;
332        let context_p_port_elem = op_iref
333            .get_sub_element(ElementName::ContextPPortRef)?
334            .get_reference_target()
335            .ok()?;
336        let client_server_operation = ClientServerOperation::try_from(operation_elem).ok()?;
337        let context_p_port = PPortPrototype::try_from(context_p_port_elem).ok()?;
338        Some((client_server_operation, context_p_port))
339    }
340}
341
342//##################################################################
343
344/// this event is unconditionally raised whenever the OS task on which it is mapped is executed
345#[derive(Debug, Clone, PartialEq, Eq, Hash)]
346pub struct OsTaskExecutionEvent(Element);
347abstraction_element!(OsTaskExecutionEvent, OsTaskExecutionEvent);
348impl IdentifiableAbstractionElement for OsTaskExecutionEvent {}
349impl AbstractRTEEvent for OsTaskExecutionEvent {}
350
351impl OsTaskExecutionEvent {
352    pub(crate) fn new(
353        name: &str,
354        parent: &Element,
355        runnable_entity: &RunnableEntity,
356    ) -> Result<Self, AutosarAbstractionError> {
357        let os_task_execution_event_elem = parent.create_named_sub_element(ElementName::OsTaskExecutionEvent, name)?;
358        let os_task_execution_event = Self(os_task_execution_event_elem);
359        os_task_execution_event.set_runnable_entity(runnable_entity)?;
360
361        Ok(os_task_execution_event)
362    }
363}
364
365//##################################################################
366
367/// raised when an error occurred during the handling of the referenced `ModeDeclarationGroup`
368#[derive(Debug, Clone, PartialEq, Eq, Hash)]
369pub struct SwcModeManagerErrorEvent(Element);
370abstraction_element!(SwcModeManagerErrorEvent, SwcModeManagerErrorEvent);
371impl IdentifiableAbstractionElement for SwcModeManagerErrorEvent {}
372impl AbstractRTEEvent for SwcModeManagerErrorEvent {}
373
374//##################################################################
375
376/// raised when the specified mode change occurs
377#[derive(Debug, Clone, PartialEq, Eq, Hash)]
378pub struct SwcModeSwitchEvent(Element);
379abstraction_element!(SwcModeSwitchEvent, SwcModeSwitchEvent);
380impl IdentifiableAbstractionElement for SwcModeSwitchEvent {}
381impl AbstractRTEEvent for SwcModeSwitchEvent {}
382
383impl SwcModeSwitchEvent {
384    pub(crate) fn new<T: Into<PortPrototype> + Clone>(
385        name: &str,
386        parent: &Element,
387        runnable: &RunnableEntity,
388        activation: ModeActivationKind,
389        context_port: &T,
390        mode_declaration: &ModeDeclaration,
391        second_mode_declaration: Option<&ModeDeclaration>,
392    ) -> Result<Self, AutosarAbstractionError> {
393        let swc_mode_switch_event = parent.create_named_sub_element(ElementName::SwcModeSwitchEvent, name)?;
394        let swc_mode_switch_event = Self(swc_mode_switch_event);
395        swc_mode_switch_event.set_runnable_entity(runnable)?;
396
397        swc_mode_switch_event.set_mode_activation_kind(activation)?;
398
399        // set the context port and mode declaration
400        let result =
401            swc_mode_switch_event.set_mode_declaration(context_port, mode_declaration, second_mode_declaration);
402        if let Err(err) = result {
403            // this operation could fail if bad parameters are provided; in this case we remove the event
404            parent.remove_sub_element(swc_mode_switch_event.0)?;
405            return Err(err);
406        }
407
408        Ok(swc_mode_switch_event)
409    }
410
411    /// Set the `ModeActivationKind` that controls when the `SwcModeSwitchEvent` is triggered
412    pub fn set_mode_activation_kind(&self, activation: ModeActivationKind) -> Result<(), AutosarAbstractionError> {
413        self.element()
414            .get_or_create_sub_element(ElementName::Activation)?
415            .set_character_data::<EnumItem>(activation.into())?;
416        Ok(())
417    }
418
419    /// Get the `ModeActivationKind` that controls when the `SwcModeSwitchEvent` is triggered
420    #[must_use]
421    pub fn mode_activation_kind(&self) -> Option<ModeActivationKind> {
422        let value = self
423            .element()
424            .get_sub_element(ElementName::Activation)?
425            .character_data()?
426            .enum_value()?;
427        ModeActivationKind::try_from(value).ok()
428    }
429
430    /// Set the `ModeDeclaration` that triggers the `SwcModeSwitchEvent`
431    ///
432    /// The second mode must be provided if the activation kind `OnTransition` is configured.
433    /// In that case only transitions between the two modes trigger the event.
434    pub fn set_mode_declaration<T: Into<PortPrototype> + Clone>(
435        &self,
436        context_port: &T,
437        mode_declaration: &ModeDeclaration,
438        second_mode_declaration: Option<&ModeDeclaration>,
439    ) -> Result<(), AutosarAbstractionError> {
440        let context_port = context_port.clone().into();
441        let interface = context_port
442            .port_interface()
443            .ok_or(AutosarAbstractionError::InvalidParameter(
444                "Invalid port lacks a port interface".to_string(),
445            ))?;
446        let PortInterface::ModeSwitchInterface(mode_switch_interface) = interface else {
447            return Err(AutosarAbstractionError::InvalidParameter(
448                "A ModeSwitchEvent must refer to a port using a ModeSwitchInterface".to_string(),
449            ));
450        };
451        let Some(interface_mode_group) = mode_switch_interface.mode_group() else {
452            return Err(AutosarAbstractionError::InvalidParameter(
453                "A ModeSwitchEvent cannot refer a port whose ModeSwitchInterface does not contain a ModeGroup"
454                    .to_string(),
455            ));
456        };
457        let Some(mode_declaration_group) = interface_mode_group.mode_declaration_group() else {
458            return Err(AutosarAbstractionError::InvalidParameter(format!(
459                "ModeGroup {} is invalid: the reference a ModeDeclarationGroup is missing",
460                interface_mode_group.name().as_deref().unwrap_or("(invalid)")
461            )));
462        };
463
464        // verify that the mode_declaration is part of the mode declaration group of the context port interface
465        if mode_declaration.mode_declaration_group()? != mode_declaration_group {
466            return Err(AutosarAbstractionError::InvalidParameter(format!(
467                "ModeDeclaration {} is not part of ModeDeclarationGroup {}",
468                mode_declaration.name().as_deref().unwrap_or("(invalid)"),
469                mode_declaration_group.name().as_deref().unwrap_or("(invalid)")
470            )));
471        }
472        // verify that the second mode_declaration is part of the mode declaration group of the context port interface
473        if let Some(second_mode_declaration) = second_mode_declaration
474            && second_mode_declaration.mode_declaration_group()? != mode_declaration_group
475        {
476            return Err(AutosarAbstractionError::InvalidParameter(format!(
477                "ModeDeclaration {} is not part of ModeDeclarationGroup {}",
478                second_mode_declaration.name().as_deref().unwrap_or("(invalid)"),
479                mode_declaration_group.name().as_deref().unwrap_or("(invalid)")
480            )));
481        }
482
483        let _ = self.element().remove_sub_element_kind(ElementName::ModeIrefs);
484        let mode_irefs_elem = self.element().create_sub_element(ElementName::ModeIrefs)?;
485
486        let mode_iref = mode_irefs_elem.create_sub_element(ElementName::ModeIref)?;
487        mode_iref
488            .create_sub_element(ElementName::ContextPortRef)?
489            .set_reference_target(context_port.element())?;
490        mode_iref
491            .create_sub_element(ElementName::ContextModeDeclarationGroupPrototypeRef)?
492            .set_reference_target(interface_mode_group.element())?;
493        mode_iref
494            .create_sub_element(ElementName::TargetModeDeclarationRef)?
495            .set_reference_target(mode_declaration.element())?;
496
497        if let Some(second_mode_declaration) = second_mode_declaration {
498            let second_mode_iref = mode_irefs_elem.create_sub_element(ElementName::ModeIref)?;
499            second_mode_iref
500                .create_sub_element(ElementName::ContextPortRef)?
501                .set_reference_target(context_port.element())?;
502            second_mode_iref
503                .create_sub_element(ElementName::ContextModeDeclarationGroupPrototypeRef)?
504                .set_reference_target(interface_mode_group.element())?;
505            second_mode_iref
506                .create_sub_element(ElementName::TargetModeDeclarationRef)?
507                .set_reference_target(second_mode_declaration.element())?;
508        }
509
510        Ok(())
511    }
512
513    /// Get the `ModeDeclaration`s that trigger the `SwcModeSwitchEvent`
514    ///
515    /// The list contains either one or two `ModeDeclaration`s depending on the `ModeActivationKind`.
516    #[must_use]
517    pub fn mode_declarations(&self) -> Option<(Vec<ModeDeclaration>, PortPrototype)> {
518        let mode_irefs_elem = self.element().get_sub_element(ElementName::ModeIrefs)?;
519        let mode_declarations = mode_irefs_elem
520            .sub_elements()
521            .filter_map(|mode_iref_elem| {
522                mode_iref_elem
523                    .get_sub_element(ElementName::TargetModeDeclarationRef)
524                    .and_then(|tref_elem| tref_elem.get_reference_target().ok())
525                    .and_then(|elem| ModeDeclaration::try_from(elem).ok())
526            })
527            .collect();
528        let port_elem = mode_irefs_elem
529            .get_sub_element(ElementName::ModeIref)?
530            .get_sub_element(ElementName::ContextPortRef)?
531            .get_reference_target()
532            .ok()?;
533        let port_proto = PortPrototype::try_from(port_elem).ok()?;
534        Some((mode_declarations, port_proto))
535    }
536}
537
538//##################################################################
539
540/// Kind of mode switch condition used for activation of an event
541#[derive(Debug, Clone, PartialEq, Eq, Hash)]
542pub enum ModeActivationKind {
543    /// On entering the mode
544    OnEntry,
545    /// On leaving the mode
546    OnExit,
547    /// on transition from the first mode to the second mode
548    OnTransition,
549}
550
551impl From<ModeActivationKind> for EnumItem {
552    fn from(activation_kind: ModeActivationKind) -> Self {
553        match activation_kind {
554            ModeActivationKind::OnEntry => EnumItem::OnEntry,
555            ModeActivationKind::OnExit => EnumItem::OnExit,
556            ModeActivationKind::OnTransition => EnumItem::OnTransition,
557        }
558    }
559}
560
561impl TryFrom<EnumItem> for ModeActivationKind {
562    type Error = AutosarAbstractionError;
563
564    fn try_from(activation_kind: EnumItem) -> Result<Self, Self::Error> {
565        match activation_kind {
566            EnumItem::OnEntry => Ok(ModeActivationKind::OnEntry),
567            EnumItem::OnExit => Ok(ModeActivationKind::OnExit),
568            EnumItem::OnTransition => Ok(ModeActivationKind::OnTransition),
569            _ => Err(AutosarAbstractionError::ValueConversionError {
570                value: activation_kind.to_string(),
571                dest: "ModeActivationKind".to_string(),
572            }),
573        }
574    }
575}
576
577//##################################################################
578
579/// raised if a hard transformer error occurs
580#[derive(Debug, Clone, PartialEq, Eq, Hash)]
581pub struct TransformerHardErrorEvent(Element);
582abstraction_element!(TransformerHardErrorEvent, TransformerHardErrorEvent);
583impl IdentifiableAbstractionElement for TransformerHardErrorEvent {}
584impl AbstractRTEEvent for TransformerHardErrorEvent {}
585
586//##################################################################
587
588/// All events that can trigger a `RunnableEntity` in the RTE
589#[derive(Debug, Clone, PartialEq, Eq, Hash)]
590pub enum RTEEvent {
591    /// raised when an asynchronous server call completed
592    AsynchronousServerCallReturnsEvent(AsynchronousServerCallReturnsEvent),
593    /// starts a runnable for background processing at low priority
594    BackgroundEvent(BackgroundEvent),
595    /// raised in response to an error during data reception
596    DataReceiveErrorEvent(DataReceiveErrorEvent),
597    /// raised when data is received
598    DataReceivedEvent(DataReceivedEvent),
599    /// raised when data has been sent
600    DataSendCompletedEvent(DataSendCompletedEvent),
601    /// raised when an implicit write access was successful or an error occurred
602    DataWriteCompletedEvent(DataWriteCompletedEvent),
603    /// raised when the referenced trigger occurred
604    ExternalTriggerOccurredEvent(ExternalTriggerOccurredEvent),
605    /// triggered once after the RTE has been started
606    InitEvent(InitEvent),
607    /// The referenced `InternalTriggeringPoint` raises this `InternalTriggerOccurredEvent`
608    InternalTriggerOccurredEvent(InternalTriggerOccurredEvent),
609    /// raised when the referenced `ModeSwitchPoint` has been acknowledged
610    ModeSwitchedAckEvent(ModeSwitchedAckEvent),
611    /// raised in order to run the server runnable of a `ClientServerOperation`
612    OperationInvokedEvent(OperationInvokedEvent),
613    /// this event is unconditionally raised whenever the OS task on which it is mapped is executed
614    OsTaskExecutionEvent(OsTaskExecutionEvent),
615    /// raised when an error occurred during the handling of the referenced `ModeDeclarationGroup`
616    SwcModeManagerErrorEvent(SwcModeManagerErrorEvent),
617    /// raised when the specified mode change occurs
618    SwcModeSwitchEvent(SwcModeSwitchEvent),
619    /// raised if a hard transformer error occurs
620    TimingEvent(TimingEvent),
621    /// raised when an error occurred during the handling of the referenced `ModeDeclarationGroup`
622    TransformerHardErrorEvent(TransformerHardErrorEvent),
623}
624
625impl AbstractionElement for RTEEvent {
626    fn element(&self) -> &Element {
627        match self {
628            RTEEvent::AsynchronousServerCallReturnsEvent(elem) => elem.element(),
629            RTEEvent::BackgroundEvent(elem) => elem.element(),
630            RTEEvent::DataReceiveErrorEvent(elem) => elem.element(),
631            RTEEvent::DataReceivedEvent(elem) => elem.element(),
632            RTEEvent::DataSendCompletedEvent(elem) => elem.element(),
633            RTEEvent::DataWriteCompletedEvent(elem) => elem.element(),
634            RTEEvent::ExternalTriggerOccurredEvent(elem) => elem.element(),
635            RTEEvent::InitEvent(elem) => elem.element(),
636            RTEEvent::InternalTriggerOccurredEvent(elem) => elem.element(),
637            RTEEvent::ModeSwitchedAckEvent(elem) => elem.element(),
638            RTEEvent::OperationInvokedEvent(elem) => elem.element(),
639            RTEEvent::OsTaskExecutionEvent(elem) => elem.element(),
640            RTEEvent::SwcModeManagerErrorEvent(elem) => elem.element(),
641            RTEEvent::SwcModeSwitchEvent(elem) => elem.element(),
642            RTEEvent::TimingEvent(elem) => elem.element(),
643            RTEEvent::TransformerHardErrorEvent(elem) => elem.element(),
644        }
645    }
646}
647
648impl TryFrom<Element> for RTEEvent {
649    type Error = AutosarAbstractionError;
650
651    fn try_from(element: Element) -> Result<Self, Self::Error> {
652        match element.element_name() {
653            ElementName::AsynchronousServerCallReturnsEvent => Ok(RTEEvent::AsynchronousServerCallReturnsEvent(
654                AsynchronousServerCallReturnsEvent(element),
655            )),
656            ElementName::BackgroundEvent => Ok(RTEEvent::BackgroundEvent(BackgroundEvent(element))),
657            ElementName::DataReceiveErrorEvent => Ok(RTEEvent::DataReceiveErrorEvent(DataReceiveErrorEvent(element))),
658            ElementName::DataReceivedEvent => Ok(RTEEvent::DataReceivedEvent(DataReceivedEvent(element))),
659            ElementName::DataSendCompletedEvent => {
660                Ok(RTEEvent::DataSendCompletedEvent(DataSendCompletedEvent(element)))
661            }
662            ElementName::DataWriteCompletedEvent => {
663                Ok(RTEEvent::DataWriteCompletedEvent(DataWriteCompletedEvent(element)))
664            }
665            ElementName::ExternalTriggerOccurredEvent => Ok(RTEEvent::ExternalTriggerOccurredEvent(
666                ExternalTriggerOccurredEvent(element),
667            )),
668            ElementName::InitEvent => Ok(RTEEvent::InitEvent(InitEvent(element))),
669            ElementName::InternalTriggerOccurredEvent => Ok(RTEEvent::InternalTriggerOccurredEvent(
670                InternalTriggerOccurredEvent(element),
671            )),
672            ElementName::ModeSwitchedAckEvent => Ok(RTEEvent::ModeSwitchedAckEvent(ModeSwitchedAckEvent(element))),
673            ElementName::OperationInvokedEvent => Ok(RTEEvent::OperationInvokedEvent(OperationInvokedEvent(element))),
674            ElementName::OsTaskExecutionEvent => Ok(RTEEvent::OsTaskExecutionEvent(OsTaskExecutionEvent(element))),
675            ElementName::SwcModeManagerErrorEvent => {
676                Ok(RTEEvent::SwcModeManagerErrorEvent(SwcModeManagerErrorEvent(element)))
677            }
678            ElementName::SwcModeSwitchEvent => Ok(RTEEvent::SwcModeSwitchEvent(SwcModeSwitchEvent(element))),
679            ElementName::TimingEvent => Ok(RTEEvent::TimingEvent(TimingEvent(element))),
680            ElementName::TransformerHardErrorEvent => {
681                Ok(RTEEvent::TransformerHardErrorEvent(TransformerHardErrorEvent(element)))
682            }
683            _ => Err(AutosarAbstractionError::ConversionError {
684                element: element.clone(),
685                dest: "RTEEvent".to_string(),
686            }),
687        }
688    }
689}
690
691impl IdentifiableAbstractionElement for RTEEvent {}
692impl AbstractRTEEvent for RTEEvent {}