Skip to main content

bpmn_engine/elements/
event.rs

1//! Event Elements
2//!
3//! Implementation of BPMN event elements with Activity/Capability traits.
4
5use crate::activity::{Activity, ActivityError, ActivityResult};
6use crate::capability::{Capability, CapabilityError, CapabilityResult, CapabilityProvider};
7use crate::engine::context::ProcessInstanceState;
8use crate::engine::ExecutionContext;
9use crate::model::{StartEvent, EndEvent, IntermediateCatchEvent, IntermediateThrowEvent};
10use async_trait::async_trait;
11use std::collections::HashMap;
12
13/// Start Event Activity
14///
15/// Implements Activity trait for StartEvent elements.
16pub struct StartEventActivity {
17    event: StartEvent,
18}
19
20impl StartEventActivity {
21    pub fn new(event: StartEvent) -> Self {
22        Self { event }
23    }
24}
25
26#[async_trait]
27impl Activity for StartEventActivity {
28    async fn execute(&self, context: &mut ExecutionContext) -> Result<ActivityResult, ActivityError> {
29        // Start events immediately continue to next elements
30        let definition = &context.process_definition;
31        let outgoing_flows = definition.get_outgoing_flows(&self.event.base.id);
32        let next_elements: Vec<String> = outgoing_flows
33            .iter()
34            .map(|flow| flow.target_ref.clone())
35            .collect();
36
37        Ok(ActivityResult::Continue { next_elements })
38    }
39
40    fn id(&self) -> &str {
41        &self.event.base.id
42    }
43
44    fn name(&self) -> Option<&str> {
45        self.event.base.name.as_deref()
46    }
47}
48
49/// End Event Activity
50///
51/// Implements Activity trait for EndEvent elements.
52pub struct EndEventActivity {
53    event: EndEvent,
54}
55
56impl EndEventActivity {
57    pub fn new(event: EndEvent) -> Self {
58        Self { event }
59    }
60}
61
62#[async_trait]
63impl Activity for EndEventActivity {
64    async fn execute(&self, context: &mut ExecutionContext) -> Result<ActivityResult, ActivityError> {
65        // End events complete the process
66        context.state = ProcessInstanceState::Completed;
67        Ok(ActivityResult::Completed { output_variables: None })
68    }
69
70    fn id(&self) -> &str {
71        &self.event.base.id
72    }
73
74    fn name(&self) -> Option<&str> {
75        self.event.base.name.as_deref()
76    }
77}
78
79/// Intermediate Catch Event Activity
80///
81/// Implements Activity trait for IntermediateCatchEvent elements.
82pub struct IntermediateCatchEventActivity {
83    event: IntermediateCatchEvent,
84}
85
86impl IntermediateCatchEventActivity {
87    pub fn new(event: IntermediateCatchEvent) -> Self {
88        Self { event }
89    }
90}
91
92#[async_trait]
93impl Activity for IntermediateCatchEventActivity {
94    async fn execute(&self, context: &mut ExecutionContext) -> Result<ActivityResult, ActivityError> {
95        // Intermediate catch events wait for the event to occur
96        // TODO: Implement event waiting based on event definition
97        Ok(ActivityResult::Waiting {
98            reason: format!(
99                "Intermediate catch event '{}' waiting for event",
100                self.event.base.id
101            ),
102        })
103    }
104
105    fn id(&self) -> &str {
106        &self.event.base.id
107    }
108
109    fn name(&self) -> Option<&str> {
110        self.event.base.name.as_deref()
111    }
112}
113
114/// Intermediate Throw Event Activity
115///
116/// Implements Activity trait for IntermediateThrowEvent elements.
117pub struct IntermediateThrowEventActivity {
118    event: IntermediateThrowEvent,
119}
120
121impl IntermediateThrowEventActivity {
122    pub fn new(event: IntermediateThrowEvent) -> Self {
123        Self { event }
124    }
125}
126
127#[async_trait]
128impl Activity for IntermediateThrowEventActivity {
129    async fn execute(&self, context: &mut ExecutionContext) -> Result<ActivityResult, ActivityError> {
130        // Intermediate throw events immediately throw the event and continue
131        // TODO: Implement event throwing based on event definition
132        let definition = &context.process_definition;
133        let outgoing_flows = definition.get_outgoing_flows(&self.event.base.id);
134        let next_elements: Vec<String> = outgoing_flows
135            .iter()
136            .map(|flow| flow.target_ref.clone())
137            .collect();
138
139        Ok(ActivityResult::Continue { next_elements })
140    }
141
142    fn id(&self) -> &str {
143        &self.event.base.id
144    }
145
146    fn name(&self) -> Option<&str> {
147        self.event.base.name.as_deref()
148    }
149}