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 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.port_interface()?;
442        let PortInterface::ModeSwitchInterface(mode_switch_interface) = interface else {
443            return Err(AutosarAbstractionError::InvalidParameter(
444                "A ModeSwitchEvent must refer to a port using a ModeSwitchInterface".to_string(),
445            ));
446        };
447        let Some(interface_mode_group) = mode_switch_interface.mode_group() else {
448            return Err(AutosarAbstractionError::InvalidParameter(
449                "A ModeSwitchEvent cannot refer a port whose ModeSwitchInterface does not contain a ModeGroup"
450                    .to_string(),
451            ));
452        };
453        let Some(mode_declaration_group) = interface_mode_group.mode_declaration_group() else {
454            return Err(AutosarAbstractionError::InvalidParameter(format!(
455                "ModeGroup {} is invalid: the reference a ModeDeclarationGroup is missing",
456                interface_mode_group.name().as_deref().unwrap_or("(invalid)")
457            )));
458        };
459
460        // verify that the mode_declaration is part of the mode declaration group of the context port interface
461        if mode_declaration.mode_declaration_group()? != mode_declaration_group {
462            return Err(AutosarAbstractionError::InvalidParameter(format!(
463                "ModeDeclaration {} is not part of ModeDeclarationGroup {}",
464                mode_declaration.name().as_deref().unwrap_or("(invalid)"),
465                mode_declaration_group.name().as_deref().unwrap_or("(invalid)")
466            )));
467        }
468        // verify that the second mode_declaration is part of the mode declaration group of the context port interface
469        if let Some(second_mode_declaration) = second_mode_declaration {
470            if second_mode_declaration.mode_declaration_group()? != mode_declaration_group {
471                return Err(AutosarAbstractionError::InvalidParameter(format!(
472                    "ModeDeclaration {} is not part of ModeDeclarationGroup {}",
473                    second_mode_declaration.name().as_deref().unwrap_or("(invalid)"),
474                    mode_declaration_group.name().as_deref().unwrap_or("(invalid)")
475                )));
476            }
477        }
478
479        let _ = self.element().remove_sub_element_kind(ElementName::ModeIrefs);
480        let mode_irefs_elem = self.element().create_sub_element(ElementName::ModeIrefs)?;
481
482        let mode_iref = mode_irefs_elem.create_sub_element(ElementName::ModeIref)?;
483        mode_iref
484            .create_sub_element(ElementName::ContextPortRef)?
485            .set_reference_target(context_port.element())?;
486        mode_iref
487            .create_sub_element(ElementName::ContextModeDeclarationGroupPrototypeRef)?
488            .set_reference_target(interface_mode_group.element())?;
489        mode_iref
490            .create_sub_element(ElementName::TargetModeDeclarationRef)?
491            .set_reference_target(mode_declaration.element())?;
492
493        if let Some(second_mode_declaration) = second_mode_declaration {
494            let second_mode_iref = mode_irefs_elem.create_sub_element(ElementName::ModeIref)?;
495            second_mode_iref
496                .create_sub_element(ElementName::ContextPortRef)?
497                .set_reference_target(context_port.element())?;
498            second_mode_iref
499                .create_sub_element(ElementName::ContextModeDeclarationGroupPrototypeRef)?
500                .set_reference_target(interface_mode_group.element())?;
501            second_mode_iref
502                .create_sub_element(ElementName::TargetModeDeclarationRef)?
503                .set_reference_target(second_mode_declaration.element())?;
504        }
505
506        Ok(())
507    }
508
509    /// Get the `ModeDeclaration`s that trigger the `SwcModeSwitchEvent`
510    ///
511    /// The list contains either one or two `ModeDeclaration`s depending on the `ModeActivationKind`.
512    #[must_use]
513    pub fn mode_declarations(&self) -> Option<(Vec<ModeDeclaration>, PortPrototype)> {
514        let mode_irefs_elem = self.element().get_sub_element(ElementName::ModeIrefs)?;
515        let mode_declarations = mode_irefs_elem
516            .sub_elements()
517            .filter_map(|mode_iref_elem| {
518                mode_iref_elem
519                    .get_sub_element(ElementName::TargetModeDeclarationRef)
520                    .and_then(|tref_elem| tref_elem.get_reference_target().ok())
521                    .and_then(|elem| ModeDeclaration::try_from(elem).ok())
522            })
523            .collect();
524        let port_elem = mode_irefs_elem
525            .get_sub_element(ElementName::ModeIref)?
526            .get_sub_element(ElementName::ContextPortRef)?
527            .get_reference_target()
528            .ok()?;
529        let port_proto = PortPrototype::try_from(port_elem).ok()?;
530        Some((mode_declarations, port_proto))
531    }
532}
533
534//##################################################################
535
536/// Kind of mode switch condition used for activation of an event
537#[derive(Debug, Clone, PartialEq, Eq, Hash)]
538pub enum ModeActivationKind {
539    /// On entering the mode
540    OnEntry,
541    /// On leaving the mode
542    OnExit,
543    /// on transition from the first mode to the second mode
544    OnTransition,
545}
546
547impl From<ModeActivationKind> for EnumItem {
548    fn from(activation_kind: ModeActivationKind) -> Self {
549        match activation_kind {
550            ModeActivationKind::OnEntry => EnumItem::OnEntry,
551            ModeActivationKind::OnExit => EnumItem::OnExit,
552            ModeActivationKind::OnTransition => EnumItem::OnTransition,
553        }
554    }
555}
556
557impl TryFrom<EnumItem> for ModeActivationKind {
558    type Error = AutosarAbstractionError;
559
560    fn try_from(activation_kind: EnumItem) -> Result<Self, Self::Error> {
561        match activation_kind {
562            EnumItem::OnEntry => Ok(ModeActivationKind::OnEntry),
563            EnumItem::OnExit => Ok(ModeActivationKind::OnExit),
564            EnumItem::OnTransition => Ok(ModeActivationKind::OnTransition),
565            _ => Err(AutosarAbstractionError::ValueConversionError {
566                value: activation_kind.to_string(),
567                dest: "ModeActivationKind".to_string(),
568            }),
569        }
570    }
571}
572
573//##################################################################
574
575/// raised if a hard transformer error occurs
576#[derive(Debug, Clone, PartialEq, Eq, Hash)]
577pub struct TransformerHardErrorEvent(Element);
578abstraction_element!(TransformerHardErrorEvent, TransformerHardErrorEvent);
579impl IdentifiableAbstractionElement for TransformerHardErrorEvent {}
580impl AbstractRTEEvent for TransformerHardErrorEvent {}
581
582//##################################################################
583
584/// All events that can trigger a `RunnableEntity` in the RTE
585#[derive(Debug, Clone, PartialEq, Eq, Hash)]
586pub enum RTEEvent {
587    /// raised when an asynchronous server call completed
588    AsynchronousServerCallReturnsEvent(AsynchronousServerCallReturnsEvent),
589    /// starts a runnable for background processing at low priority
590    BackgroundEvent(BackgroundEvent),
591    /// raised in response to an error during data reception
592    DataReceiveErrorEvent(DataReceiveErrorEvent),
593    /// raised when data is received
594    DataReceivedEvent(DataReceivedEvent),
595    /// raised when data has been sent
596    DataSendCompletedEvent(DataSendCompletedEvent),
597    /// raised when an implicit write access was successful or an error occurred
598    DataWriteCompletedEvent(DataWriteCompletedEvent),
599    /// raised when the referenced trigger occurred
600    ExternalTriggerOccurredEvent(ExternalTriggerOccurredEvent),
601    /// triggered once after the RTE has been started
602    InitEvent(InitEvent),
603    /// The referenced `InternalTriggeringPoint` raises this `InternalTriggerOccurredEvent`
604    InternalTriggerOccurredEvent(InternalTriggerOccurredEvent),
605    /// raised when the referenced `ModeSwitchPoint` has been acknowledged
606    ModeSwitchedAckEvent(ModeSwitchedAckEvent),
607    /// raised in order to run the server runnable of a `ClientServerOperation`
608    OperationInvokedEvent(OperationInvokedEvent),
609    /// this event is unconditionally raised whenever the OS task on which it is mapped is executed
610    OsTaskExecutionEvent(OsTaskExecutionEvent),
611    /// raised when an error occurred during the handling of the referenced `ModeDeclarationGroup`
612    SwcModeManagerErrorEvent(SwcModeManagerErrorEvent),
613    /// raised when the specified mode change occurs
614    SwcModeSwitchEvent(SwcModeSwitchEvent),
615    /// raised if a hard transformer error occurs
616    TimingEvent(TimingEvent),
617    /// raised when an error occurred during the handling of the referenced `ModeDeclarationGroup`
618    TransformerHardErrorEvent(TransformerHardErrorEvent),
619}
620
621impl AbstractionElement for RTEEvent {
622    fn element(&self) -> &Element {
623        match self {
624            RTEEvent::AsynchronousServerCallReturnsEvent(elem) => elem.element(),
625            RTEEvent::BackgroundEvent(elem) => elem.element(),
626            RTEEvent::DataReceiveErrorEvent(elem) => elem.element(),
627            RTEEvent::DataReceivedEvent(elem) => elem.element(),
628            RTEEvent::DataSendCompletedEvent(elem) => elem.element(),
629            RTEEvent::DataWriteCompletedEvent(elem) => elem.element(),
630            RTEEvent::ExternalTriggerOccurredEvent(elem) => elem.element(),
631            RTEEvent::InitEvent(elem) => elem.element(),
632            RTEEvent::InternalTriggerOccurredEvent(elem) => elem.element(),
633            RTEEvent::ModeSwitchedAckEvent(elem) => elem.element(),
634            RTEEvent::OperationInvokedEvent(elem) => elem.element(),
635            RTEEvent::OsTaskExecutionEvent(elem) => elem.element(),
636            RTEEvent::SwcModeManagerErrorEvent(elem) => elem.element(),
637            RTEEvent::SwcModeSwitchEvent(elem) => elem.element(),
638            RTEEvent::TimingEvent(elem) => elem.element(),
639            RTEEvent::TransformerHardErrorEvent(elem) => elem.element(),
640        }
641    }
642}
643
644impl TryFrom<Element> for RTEEvent {
645    type Error = AutosarAbstractionError;
646
647    fn try_from(element: Element) -> Result<Self, Self::Error> {
648        match element.element_name() {
649            ElementName::AsynchronousServerCallReturnsEvent => Ok(RTEEvent::AsynchronousServerCallReturnsEvent(
650                AsynchronousServerCallReturnsEvent(element),
651            )),
652            ElementName::BackgroundEvent => Ok(RTEEvent::BackgroundEvent(BackgroundEvent(element))),
653            ElementName::DataReceiveErrorEvent => Ok(RTEEvent::DataReceiveErrorEvent(DataReceiveErrorEvent(element))),
654            ElementName::DataReceivedEvent => Ok(RTEEvent::DataReceivedEvent(DataReceivedEvent(element))),
655            ElementName::DataSendCompletedEvent => {
656                Ok(RTEEvent::DataSendCompletedEvent(DataSendCompletedEvent(element)))
657            }
658            ElementName::DataWriteCompletedEvent => {
659                Ok(RTEEvent::DataWriteCompletedEvent(DataWriteCompletedEvent(element)))
660            }
661            ElementName::ExternalTriggerOccurredEvent => Ok(RTEEvent::ExternalTriggerOccurredEvent(
662                ExternalTriggerOccurredEvent(element),
663            )),
664            ElementName::InitEvent => Ok(RTEEvent::InitEvent(InitEvent(element))),
665            ElementName::InternalTriggerOccurredEvent => Ok(RTEEvent::InternalTriggerOccurredEvent(
666                InternalTriggerOccurredEvent(element),
667            )),
668            ElementName::ModeSwitchedAckEvent => Ok(RTEEvent::ModeSwitchedAckEvent(ModeSwitchedAckEvent(element))),
669            ElementName::OperationInvokedEvent => Ok(RTEEvent::OperationInvokedEvent(OperationInvokedEvent(element))),
670            ElementName::OsTaskExecutionEvent => Ok(RTEEvent::OsTaskExecutionEvent(OsTaskExecutionEvent(element))),
671            ElementName::SwcModeManagerErrorEvent => {
672                Ok(RTEEvent::SwcModeManagerErrorEvent(SwcModeManagerErrorEvent(element)))
673            }
674            ElementName::SwcModeSwitchEvent => Ok(RTEEvent::SwcModeSwitchEvent(SwcModeSwitchEvent(element))),
675            ElementName::TimingEvent => Ok(RTEEvent::TimingEvent(TimingEvent(element))),
676            ElementName::TransformerHardErrorEvent => {
677                Ok(RTEEvent::TransformerHardErrorEvent(TransformerHardErrorEvent(element)))
678            }
679            _ => Err(AutosarAbstractionError::ConversionError {
680                element: element.clone(),
681                dest: "RTEEvent".to_string(),
682            }),
683        }
684    }
685}
686
687impl IdentifiableAbstractionElement for RTEEvent {}
688impl AbstractRTEEvent for RTEEvent {}