Skip to main content

bpmn_engine/model/
elements.rs

1//! BPMN Model Elements
2//!
3//! Internal representation of BPMN elements after parsing from JSON.
4
5use crate::model::json::*;
6use std::collections::HashMap;
7
8/// Process Definition
9///
10/// Internal representation of a BPMN process definition.
11#[derive(Debug, Clone)]
12pub struct ProcessDefinition {
13    /// Process ID
14    pub id: String,
15    /// Process name
16    pub name: Option<String>,
17    /// Process type
18    pub process_type: String,
19    /// Is executable
20    pub is_executable: bool,
21    /// Process elements indexed by ID
22    pub elements: HashMap<String, ProcessElement>,
23    /// Sequence flows indexed by ID
24    pub flows: HashMap<String, SequenceFlow>,
25    /// Variables
26    pub variables: HashMap<String, Variable>,
27}
28
29impl ProcessDefinition {
30    /// Create a new process definition from JSON
31    pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
32        let json_process: BpmnJsonProcess = serde_json::from_str(json)?;
33        Self::from_bpmn_json(json_process)
34    }
35
36    /// Create a new process definition from XML
37    pub fn from_xml(xml: &str) -> Result<Self, crate::model::format::ParseError> {
38        crate::model::xml::parse_bpmn_xml(xml)
39    }
40
41    /// Create a new process definition with automatic format detection
42    pub fn from_auto(input: &str) -> Result<(Self, crate::model::format::BpmnFormat), crate::model::format::ParseError> {
43        crate::model::format::AutoParser::parse(input)
44    }
45
46    /// Serialize to JSON
47    pub fn to_json(&self) -> Result<String, crate::model::format::SerializeError> {
48        let mut json_elements = Vec::new();
49        
50        // Convert elements to JSON
51        for element in self.elements.values() {
52            json_elements.push(element.to_json_element());
53        }
54        
55        // Convert flows to JSON
56        for flow in self.flows.values() {
57            json_elements.push(BpmnJsonElement::SequenceFlow(flow.to_json()));
58        }
59        
60        let json_process = BpmnJsonProcess {
61            id: self.id.clone(),
62            name: self.name.clone(),
63            process_type: self.process_type.clone(),
64            is_executable: self.is_executable,
65            elements: json_elements,
66            variables: self.variables.iter().map(|(k, v)| {
67                (k.clone(), crate::model::json::BpmnJsonVariable {
68                    name: v.name.clone(),
69                    variable_type: v.variable_type.clone(),
70                    default_value: v.default_value.clone(),
71                })
72            }).collect(),
73        };
74        serde_json::to_string_pretty(&json_process).map_err(crate::model::format::SerializeError::Json)
75    }
76
77    /// Serialize to XML
78    pub fn to_xml(&self) -> Result<String, crate::model::format::SerializeError> {
79        crate::model::xml::serialize_bpmn_xml(self)
80    }
81
82    /// Create from BPMn JSON structure
83    pub fn from_bpmn_json(json_process: BpmnJsonProcess) -> Result<Self, serde_json::Error> {
84        let mut elements = HashMap::new();
85        let mut flows = HashMap::new();
86
87        for element in json_process.elements {
88            match element {
89                BpmnJsonElement::SequenceFlow(flow) => {
90                    let seq_flow = SequenceFlow::from_json(flow);
91                    flows.insert(seq_flow.id.clone(), seq_flow);
92                }
93                _ => {
94                    let process_elem = ProcessElement::from_json_element(element)?;
95                    elements.insert(process_elem.id().to_string(), process_elem);
96                }
97            }
98        }
99
100        Ok(Self {
101            id: json_process.id,
102            name: json_process.name,
103            process_type: json_process.process_type,
104            is_executable: json_process.is_executable,
105            elements,
106            flows,
107            variables: json_process
108                .variables
109                .into_iter()
110                .map(|(k, v)| (k, Variable::from_json(v)))
111                .collect(),
112        })
113    }
114
115    /// Get element by ID
116    pub fn get_element(&self, id: &str) -> Option<&ProcessElement> {
117        self.elements.get(id)
118    }
119
120    /// Get sequence flow by ID
121    pub fn get_flow(&self, id: &str) -> Option<&SequenceFlow> {
122        self.flows.get(id)
123    }
124
125    /// Get outgoing flows from an element
126    pub fn get_outgoing_flows(&self, element_id: &str) -> Vec<&SequenceFlow> {
127        self.flows
128            .values()
129            .filter(|flow| flow.source_ref == element_id)
130            .collect()
131    }
132
133    /// Get incoming flows to an element
134    pub fn get_incoming_flows(&self, element_id: &str) -> Vec<&SequenceFlow> {
135        self.flows
136            .values()
137            .filter(|flow| flow.target_ref == element_id)
138            .collect()
139    }
140}
141
142/// Process Element
143///
144/// Represents any executable BPMN element (task, gateway, event).
145#[derive(Debug, Clone)]
146pub enum ProcessElement {
147    /// Start Event
148    StartEvent(StartEvent),
149    /// End Event
150    EndEvent(EndEvent),
151    /// Intermediate Catch Event
152    IntermediateCatchEvent(IntermediateCatchEvent),
153    /// Intermediate Throw Event
154    IntermediateThrowEvent(IntermediateThrowEvent),
155    /// Service Task
156    ServiceTask(ServiceTask),
157    /// User Task
158    UserTask(UserTask),
159    /// Script Task
160    ScriptTask(ScriptTask),
161    /// Manual Task
162    ManualTask(ManualTask),
163    /// Exclusive Gateway
164    ExclusiveGateway(ExclusiveGateway),
165    /// Parallel Gateway
166    ParallelGateway(ParallelGateway),
167    /// Inclusive Gateway
168    InclusiveGateway(InclusiveGateway),
169}
170
171impl ProcessElement {
172    pub fn from_json_element(element: BpmnJsonElement) -> Result<Self, serde_json::Error> {
173        match element {
174            BpmnJsonElement::StartEvent(e) => Ok(ProcessElement::StartEvent(StartEvent::from_json(e))),
175            BpmnJsonElement::EndEvent(e) => Ok(ProcessElement::EndEvent(EndEvent::from_json(e))),
176            BpmnJsonElement::IntermediateCatchEvent(e) => {
177                Ok(ProcessElement::IntermediateCatchEvent(IntermediateCatchEvent::from_json(e)))
178            }
179            BpmnJsonElement::IntermediateThrowEvent(e) => {
180                Ok(ProcessElement::IntermediateThrowEvent(IntermediateThrowEvent::from_json(e)))
181            }
182            BpmnJsonElement::ServiceTask(e) => {
183                Ok(ProcessElement::ServiceTask(ServiceTask::from_json(e)))
184            }
185            BpmnJsonElement::UserTask(e) => Ok(ProcessElement::UserTask(UserTask::from_json(e))),
186            BpmnJsonElement::ScriptTask(e) => Ok(ProcessElement::ScriptTask(ScriptTask::from_json(e))),
187            BpmnJsonElement::ManualTask(e) => Ok(ProcessElement::ManualTask(ManualTask::from_json(e))),
188            BpmnJsonElement::ExclusiveGateway(e) => {
189                Ok(ProcessElement::ExclusiveGateway(ExclusiveGateway::from_json(e)))
190            }
191            BpmnJsonElement::ParallelGateway(e) => {
192                Ok(ProcessElement::ParallelGateway(ParallelGateway::from_json(e)))
193            }
194            BpmnJsonElement::InclusiveGateway(e) => {
195                Ok(ProcessElement::InclusiveGateway(InclusiveGateway::from_json(e)))
196            }
197            BpmnJsonElement::SequenceFlow(_) => {
198                use serde::de::Error;
199                Err(serde_json::Error::custom("SequenceFlow should be handled separately"))
200            }
201        }
202    }
203
204    pub fn id(&self) -> &str {
205        match self {
206            ProcessElement::StartEvent(e) => &e.base.id,
207            ProcessElement::EndEvent(e) => &e.base.id,
208            ProcessElement::IntermediateCatchEvent(e) => &e.base.id,
209            ProcessElement::IntermediateThrowEvent(e) => &e.base.id,
210            ProcessElement::ServiceTask(e) => &e.base.id,
211            ProcessElement::UserTask(e) => &e.base.id,
212            ProcessElement::ScriptTask(e) => &e.base.id,
213            ProcessElement::ManualTask(e) => &e.base.id,
214            ProcessElement::ExclusiveGateway(e) => &e.base.id,
215            ProcessElement::ParallelGateway(e) => &e.base.id,
216            ProcessElement::InclusiveGateway(e) => &e.base.id,
217        }
218    }
219
220    pub fn to_json_element(&self) -> BpmnJsonElement {
221        match self {
222            ProcessElement::StartEvent(e) => BpmnJsonElement::StartEvent(e.to_json()),
223            ProcessElement::EndEvent(e) => BpmnJsonElement::EndEvent(e.to_json()),
224            ProcessElement::IntermediateCatchEvent(e) => BpmnJsonElement::IntermediateCatchEvent(e.to_json()),
225            ProcessElement::IntermediateThrowEvent(e) => BpmnJsonElement::IntermediateThrowEvent(e.to_json()),
226            ProcessElement::ServiceTask(e) => BpmnJsonElement::ServiceTask(e.to_json()),
227            ProcessElement::UserTask(e) => BpmnJsonElement::UserTask(e.to_json()),
228            ProcessElement::ScriptTask(e) => BpmnJsonElement::ScriptTask(e.to_json()),
229            ProcessElement::ManualTask(e) => BpmnJsonElement::ManualTask(e.to_json()),
230            ProcessElement::ExclusiveGateway(e) => BpmnJsonElement::ExclusiveGateway(e.to_json()),
231            ProcessElement::ParallelGateway(e) => BpmnJsonElement::ParallelGateway(e.to_json()),
232            ProcessElement::InclusiveGateway(e) => BpmnJsonElement::InclusiveGateway(e.to_json()),
233        }
234    }
235}
236
237/// Base element properties
238#[derive(Debug, Clone)]
239pub struct ElementBase {
240    pub id: String,
241    pub name: Option<String>,
242    pub documentation: Option<String>,
243}
244
245impl ElementBase {
246    pub fn from_json(base: BpmnJsonElementBase) -> Self {
247        Self {
248            id: base.id,
249            name: base.name,
250            documentation: base.documentation,
251        }
252    }
253}
254
255/// Start Event
256#[derive(Debug, Clone)]
257pub struct StartEvent {
258    pub base: ElementBase,
259    pub event_definition: Option<EventDefinition>,
260}
261
262impl StartEvent {
263    pub fn from_json(json: BpmnJsonStartEvent) -> Self {
264        Self {
265            base: ElementBase::from_json(json.base),
266            event_definition: json.event_definition.map(EventDefinition::from_json),
267        }
268    }
269
270    pub fn to_json(&self) -> BpmnJsonStartEvent {
271        BpmnJsonStartEvent {
272            base: BpmnJsonElementBase {
273                id: self.base.id.clone(),
274                name: self.base.name.clone(),
275                documentation: self.base.documentation.clone(),
276            },
277            event_definition: self.event_definition.as_ref().map(EventDefinition::to_json),
278        }
279    }
280}
281
282/// End Event
283#[derive(Debug, Clone)]
284pub struct EndEvent {
285    pub base: ElementBase,
286    pub event_definition: Option<EventDefinition>,
287}
288
289impl EndEvent {
290    pub fn from_json(json: BpmnJsonEndEvent) -> Self {
291        Self {
292            base: ElementBase::from_json(json.base),
293            event_definition: json.event_definition.map(EventDefinition::from_json),
294        }
295    }
296
297    pub fn to_json(&self) -> BpmnJsonEndEvent {
298        BpmnJsonEndEvent {
299            base: BpmnJsonElementBase {
300                id: self.base.id.clone(),
301                name: self.base.name.clone(),
302                documentation: self.base.documentation.clone(),
303            },
304            event_definition: self.event_definition.as_ref().map(EventDefinition::to_json),
305        }
306    }
307}
308
309/// Intermediate Catch Event
310#[derive(Debug, Clone)]
311pub struct IntermediateCatchEvent {
312    pub base: ElementBase,
313    pub event_definition: Option<EventDefinition>,
314}
315
316impl IntermediateCatchEvent {
317    pub fn from_json(json: BpmnJsonIntermediateCatchEvent) -> Self {
318        Self {
319            base: ElementBase::from_json(json.base),
320            event_definition: json.event_definition.map(EventDefinition::from_json),
321        }
322    }
323
324    pub fn to_json(&self) -> BpmnJsonIntermediateCatchEvent {
325        BpmnJsonIntermediateCatchEvent {
326            base: BpmnJsonElementBase {
327                id: self.base.id.clone(),
328                name: self.base.name.clone(),
329                documentation: self.base.documentation.clone(),
330            },
331            event_definition: self.event_definition.as_ref().map(EventDefinition::to_json),
332        }
333    }
334}
335
336/// Intermediate Throw Event
337#[derive(Debug, Clone)]
338pub struct IntermediateThrowEvent {
339    pub base: ElementBase,
340    pub event_definition: Option<EventDefinition>,
341}
342
343impl IntermediateThrowEvent {
344    pub fn from_json(json: BpmnJsonIntermediateThrowEvent) -> Self {
345        Self {
346            base: ElementBase::from_json(json.base),
347            event_definition: json.event_definition.map(EventDefinition::from_json),
348        }
349    }
350
351    pub fn to_json(&self) -> BpmnJsonIntermediateThrowEvent {
352        BpmnJsonIntermediateThrowEvent {
353            base: BpmnJsonElementBase {
354                id: self.base.id.clone(),
355                name: self.base.name.clone(),
356                documentation: self.base.documentation.clone(),
357            },
358            event_definition: self.event_definition.as_ref().map(EventDefinition::to_json),
359        }
360    }
361}
362
363/// Service Task
364#[derive(Debug, Clone)]
365pub struct ServiceTask {
366    pub base: ElementBase,
367    pub implementation: Option<String>,
368    pub operation_ref: Option<String>,
369    pub io_mapping: IoMapping,
370}
371
372impl ServiceTask {
373    pub fn from_json(json: BpmnJsonServiceTask) -> Self {
374        Self {
375            base: ElementBase::from_json(json.base),
376            implementation: json.implementation,
377            operation_ref: json.operation_ref,
378            io_mapping: IoMapping::from_json(json.io_mapping),
379        }
380    }
381
382    pub fn to_json(&self) -> BpmnJsonServiceTask {
383        BpmnJsonServiceTask {
384            base: BpmnJsonElementBase {
385                id: self.base.id.clone(),
386                name: self.base.name.clone(),
387                documentation: self.base.documentation.clone(),
388            },
389            implementation: self.implementation.clone(),
390            operation_ref: self.operation_ref.clone(),
391            io_mapping: self.io_mapping.to_json(),
392        }
393    }
394}
395
396/// User Task
397#[derive(Debug, Clone)]
398pub struct UserTask {
399    pub base: ElementBase,
400    pub assignment: Option<Assignment>,
401    pub form_key: Option<String>,
402}
403
404impl UserTask {
405    pub fn from_json(json: BpmnJsonUserTask) -> Self {
406        Self {
407            base: ElementBase::from_json(json.base),
408            assignment: json.assignment.map(Assignment::from_json),
409            form_key: json.form_key,
410        }
411    }
412
413    pub fn to_json(&self) -> BpmnJsonUserTask {
414        BpmnJsonUserTask {
415            base: BpmnJsonElementBase {
416                id: self.base.id.clone(),
417                name: self.base.name.clone(),
418                documentation: self.base.documentation.clone(),
419            },
420            assignment: self.assignment.as_ref().map(Assignment::to_json),
421            form_key: self.form_key.clone(),
422        }
423    }
424}
425
426/// Script Task
427#[derive(Debug, Clone)]
428pub struct ScriptTask {
429    pub base: ElementBase,
430    pub script_format: Option<String>,
431    pub script: Option<String>,
432}
433
434impl ScriptTask {
435    pub fn from_json(json: BpmnJsonScriptTask) -> Self {
436        Self {
437            base: ElementBase::from_json(json.base),
438            script_format: json.script_format,
439            script: json.script,
440        }
441    }
442
443    pub fn to_json(&self) -> BpmnJsonScriptTask {
444        BpmnJsonScriptTask {
445            base: BpmnJsonElementBase {
446                id: self.base.id.clone(),
447                name: self.base.name.clone(),
448                documentation: self.base.documentation.clone(),
449            },
450            script_format: self.script_format.clone(),
451            script: self.script.clone(),
452        }
453    }
454}
455
456/// Manual Task
457#[derive(Debug, Clone)]
458pub struct ManualTask {
459    pub base: ElementBase,
460}
461
462impl ManualTask {
463    pub fn from_json(json: BpmnJsonManualTask) -> Self {
464        Self {
465            base: ElementBase::from_json(json.base),
466        }
467    }
468
469    pub fn to_json(&self) -> BpmnJsonManualTask {
470        BpmnJsonManualTask {
471            base: BpmnJsonElementBase {
472                id: self.base.id.clone(),
473                name: self.base.name.clone(),
474                documentation: self.base.documentation.clone(),
475            },
476        }
477    }
478}
479
480/// Exclusive Gateway
481#[derive(Debug, Clone)]
482pub struct ExclusiveGateway {
483    pub base: ElementBase,
484    pub default_flow: Option<String>,
485}
486
487impl ExclusiveGateway {
488    pub fn from_json(json: BpmnJsonExclusiveGateway) -> Self {
489        Self {
490            base: ElementBase::from_json(json.base),
491            default_flow: json.default_flow,
492        }
493    }
494
495    pub fn to_json(&self) -> BpmnJsonExclusiveGateway {
496        BpmnJsonExclusiveGateway {
497            base: BpmnJsonElementBase {
498                id: self.base.id.clone(),
499                name: self.base.name.clone(),
500                documentation: self.base.documentation.clone(),
501            },
502            default_flow: self.default_flow.clone(),
503        }
504    }
505}
506
507/// Parallel Gateway
508#[derive(Debug, Clone)]
509pub struct ParallelGateway {
510    pub base: ElementBase,
511}
512
513impl ParallelGateway {
514    pub fn from_json(json: BpmnJsonParallelGateway) -> Self {
515        Self {
516            base: ElementBase::from_json(json.base),
517        }
518    }
519
520    pub fn to_json(&self) -> BpmnJsonParallelGateway {
521        BpmnJsonParallelGateway {
522            base: BpmnJsonElementBase {
523                id: self.base.id.clone(),
524                name: self.base.name.clone(),
525                documentation: self.base.documentation.clone(),
526            },
527        }
528    }
529}
530
531/// Inclusive Gateway
532#[derive(Debug, Clone)]
533pub struct InclusiveGateway {
534    pub base: ElementBase,
535    pub default_flow: Option<String>,
536}
537
538impl InclusiveGateway {
539    pub fn from_json(json: BpmnJsonInclusiveGateway) -> Self {
540        Self {
541            base: ElementBase::from_json(json.base),
542            default_flow: json.default_flow,
543        }
544    }
545
546    pub fn to_json(&self) -> BpmnJsonInclusiveGateway {
547        BpmnJsonInclusiveGateway {
548            base: BpmnJsonElementBase {
549                id: self.base.id.clone(),
550                name: self.base.name.clone(),
551                documentation: self.base.documentation.clone(),
552            },
553            default_flow: self.default_flow.clone(),
554        }
555    }
556}
557
558/// Sequence Flow
559#[derive(Debug, Clone)]
560pub struct SequenceFlow {
561    pub id: String,
562    pub name: Option<String>,
563    pub source_ref: String,
564    pub target_ref: String,
565    pub condition_expression: Option<ConditionExpression>,
566}
567
568impl SequenceFlow {
569    pub fn from_json(json: BpmnJsonSequenceFlow) -> Self {
570        Self {
571            id: json.base.id,
572            name: json.base.name,
573            source_ref: json.source_ref,
574            target_ref: json.target_ref,
575            condition_expression: json.condition_expression.map(ConditionExpression::from_json),
576        }
577    }
578
579    pub fn to_json(&self) -> BpmnJsonSequenceFlow {
580        BpmnJsonSequenceFlow {
581            base: BpmnJsonElementBase {
582                id: self.id.clone(),
583                name: self.name.clone(),
584                documentation: None,
585            },
586            source_ref: self.source_ref.clone(),
587            target_ref: self.target_ref.clone(),
588            condition_expression: self.condition_expression.as_ref().map(ConditionExpression::to_json),
589        }
590    }
591}
592
593/// Event Definition
594#[derive(Debug, Clone)]
595pub enum EventDefinition {
596    Message { message_ref: Option<String> },
597    Timer { time_definition: Option<String> },
598    Signal { signal_ref: Option<String> },
599    Error { error_ref: Option<String> },
600    Escalation { escalation_ref: Option<String> },
601    Cancel,
602    Compensation { activity_ref: Option<String> },
603    Conditional { condition: Option<ConditionExpression> },
604    Link { name: Option<String> },
605    Terminate,
606    None,
607}
608
609impl EventDefinition {
610    pub fn from_json(json: BpmnJsonEventDefinition) -> Self {
611        match json {
612            BpmnJsonEventDefinition::Message { message_ref } => EventDefinition::Message { message_ref },
613            BpmnJsonEventDefinition::Timer { time_definition } => EventDefinition::Timer { time_definition },
614            BpmnJsonEventDefinition::Signal { signal_ref } => EventDefinition::Signal { signal_ref },
615            BpmnJsonEventDefinition::Error { error_ref } => EventDefinition::Error { error_ref },
616            BpmnJsonEventDefinition::Escalation { escalation_ref } => {
617                EventDefinition::Escalation { escalation_ref }
618            }
619            BpmnJsonEventDefinition::Cancel => EventDefinition::Cancel,
620            BpmnJsonEventDefinition::Compensation { activity_ref } => {
621                EventDefinition::Compensation { activity_ref }
622            }
623            BpmnJsonEventDefinition::Conditional { condition } => {
624                EventDefinition::Conditional {
625                    condition: condition.map(ConditionExpression::from_json),
626                }
627            }
628            BpmnJsonEventDefinition::Link { name } => EventDefinition::Link { name },
629            BpmnJsonEventDefinition::Terminate => EventDefinition::Terminate,
630            BpmnJsonEventDefinition::None => EventDefinition::None,
631        }
632    }
633
634    pub fn to_json(&self) -> BpmnJsonEventDefinition {
635        match self {
636            EventDefinition::Message { message_ref } => BpmnJsonEventDefinition::Message { message_ref: message_ref.clone() },
637            EventDefinition::Timer { time_definition } => BpmnJsonEventDefinition::Timer { time_definition: time_definition.clone() },
638            EventDefinition::Signal { signal_ref } => BpmnJsonEventDefinition::Signal { signal_ref: signal_ref.clone() },
639            EventDefinition::Error { error_ref } => BpmnJsonEventDefinition::Error { error_ref: error_ref.clone() },
640            EventDefinition::Escalation { escalation_ref } => BpmnJsonEventDefinition::Escalation { escalation_ref: escalation_ref.clone() },
641            EventDefinition::Cancel => BpmnJsonEventDefinition::Cancel,
642            EventDefinition::Compensation { activity_ref } => BpmnJsonEventDefinition::Compensation { activity_ref: activity_ref.clone() },
643            EventDefinition::Conditional { condition } => BpmnJsonEventDefinition::Conditional {
644                condition: condition.as_ref().map(ConditionExpression::to_json),
645            },
646            EventDefinition::Link { name } => BpmnJsonEventDefinition::Link { name: name.clone() },
647            EventDefinition::Terminate => BpmnJsonEventDefinition::Terminate,
648            EventDefinition::None => BpmnJsonEventDefinition::None,
649        }
650    }
651}
652
653/// Condition Expression
654#[derive(Debug, Clone)]
655pub struct ConditionExpression {
656    pub language: Option<String>,
657    pub body: String,
658}
659
660impl ConditionExpression {
661    pub fn from_json(json: BpmnJsonConditionExpression) -> Self {
662        Self {
663            language: json.language,
664            body: json.body,
665        }
666    }
667
668    pub fn to_json(&self) -> BpmnJsonConditionExpression {
669        BpmnJsonConditionExpression {
670            language: self.language.clone(),
671            body: self.body.clone(),
672        }
673    }
674}
675
676/// Input/Output Mapping
677#[derive(Debug, Clone, Default)]
678pub struct IoMapping {
679    pub input_parameters: Vec<IoParameter>,
680    pub output_parameters: Vec<IoParameter>,
681}
682
683impl IoMapping {
684    pub fn from_json(json: BpmnJsonIoMapping) -> Self {
685        Self {
686            input_parameters: json.input_parameters.into_iter().map(IoParameter::from_json).collect(),
687            output_parameters: json.output_parameters.into_iter().map(IoParameter::from_json).collect(),
688        }
689    }
690
691    pub fn to_json(&self) -> BpmnJsonIoMapping {
692        BpmnJsonIoMapping {
693            input_parameters: self.input_parameters.iter().map(IoParameter::to_json).collect(),
694            output_parameters: self.output_parameters.iter().map(IoParameter::to_json).collect(),
695        }
696    }
697}
698
699/// Input/Output Parameter
700#[derive(Debug, Clone)]
701pub struct IoParameter {
702    pub name: String,
703    pub source: Option<String>,
704    pub target: Option<String>,
705    pub value: Option<String>,
706}
707
708impl IoParameter {
709    pub fn from_json(json: BpmnJsonIoParameter) -> Self {
710        Self {
711            name: json.name,
712            source: json.source,
713            target: json.target,
714            value: json.value,
715        }
716    }
717
718    pub fn to_json(&self) -> BpmnJsonIoParameter {
719        BpmnJsonIoParameter {
720            name: self.name.clone(),
721            source: self.source.clone(),
722            target: self.target.clone(),
723            value: self.value.clone(),
724        }
725    }
726}
727
728/// Assignment
729#[derive(Debug, Clone)]
730pub struct Assignment {
731    pub assignment_type: String,
732    pub value: String,
733}
734
735impl Assignment {
736    pub fn from_json(json: BpmnJsonAssignment) -> Self {
737        Self {
738            assignment_type: json.assignment_type,
739            value: json.value,
740        }
741    }
742
743    pub fn to_json(&self) -> BpmnJsonAssignment {
744        BpmnJsonAssignment {
745            assignment_type: self.assignment_type.clone(),
746            value: self.value.clone(),
747        }
748    }
749}
750
751/// Variable
752#[derive(Debug, Clone)]
753pub struct Variable {
754    pub name: String,
755    pub variable_type: Option<String>,
756    pub default_value: Option<serde_json::Value>,
757}
758
759impl Variable {
760    pub fn from_json(json: BpmnJsonVariable) -> Self {
761        Self {
762            name: json.name,
763            variable_type: json.variable_type,
764            default_value: json.default_value,
765        }
766    }
767}
768