1use crate::{
2 BusinessProcessModelAndNotation,
3 element::BPMNElement,
4 elements::collapsed_pool::BPMNCollapsedPool,
5 stochastic_business_process_model_and_notation::StochasticBusinessProcessModelAndNotation,
6 traits::{objectable::BPMNObject, writable::Writable},
7};
8use anyhow::Result;
9use quick_xml::{
10 Writer,
11 events::{BytesDecl, BytesEnd, BytesStart, Event},
12};
13use std::io::Write;
14
15impl BusinessProcessModelAndNotation {
16 pub fn export_to_writer(&self, f: &mut dyn Write) -> Result<()> {
17 let mut x = Writer::new_with_indent(f, b'\t', 1);
18
19 x.write_event(Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), None)))?;
21
22 let mut bytes_start = BytesStart::new("definitions").with_attributes([
24 ("id", self.definitions_id.as_str()),
25 ("xmlns", "http://www.omg.org/spec/BPMN/20100524/MODEL"),
26 ("exporter", "Ebi-bpmn"),
27 ]);
28 if self.stochastic_namespace {
29 bytes_start = bytes_start
30 .with_attributes([(("xmlns:sbpmn", "https://www.ebitools.org/sbpmn/20260305"))]);
31 }
32 x.write_event(Event::Start(bytes_start))?;
33
34 if let Some(collaboration_id) = &self.collaboration_id {
36 x.write_event(Event::Start(
37 BytesStart::new("collaboration")
38 .with_attributes([("id", collaboration_id.as_str())]),
39 ))?;
40
41 self.elements
43 .iter()
44 .filter_map(|element| {
45 if let BPMNElement::CollapsedPool(p) = element {
46 Some(p)
47 } else {
48 None
49 }
50 })
51 .collect::<Vec<_>>()
52 .write(&mut x, self, self)?;
53
54 for element in &self.elements {
56 if element.is_collapsed_pool() {
57 let mut el = x
58 .create_element("participant")
59 .with_attributes([("id", element.id())]);
60 if let BPMNElement::CollapsedPool(BPMNCollapsedPool {
61 name: Some(name), ..
62 }) = element
63 {
64 el = el.with_attribute(("name", name.as_str()));
65 }
66 el.write_empty()?;
67 }
68 }
69
70 self.message_flows.write(&mut x, self, self)?;
72
73 x.write_event(Event::End(BytesEnd::new("collaboration")))?;
74 }
75
76 self.elements.write(&mut x, self, self)?;
77
78 x.write_event(Event::End(BytesEnd::new("definitions")))?;
79
80 Ok(())
81 }
82}
83
84impl StochasticBusinessProcessModelAndNotation {
85 pub fn export_to_writer(&self, f: &mut dyn Write) -> Result<()> {
86 self.bpmn.export_to_writer(f)
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use crate::{
93 BusinessProcessModelAndNotation,
94 stochastic_business_process_model_and_notation::StochasticBusinessProcessModelAndNotation,
95 };
96 use std::fs::{self};
97
98 #[test]
99 fn bpmn_export_import() {
100 let fin = fs::read_to_string("testfiles/model-lanes.bpmn").unwrap();
101 let bpmn = fin.parse::<BusinessProcessModelAndNotation>().unwrap();
102
103 let mut f = vec![];
104 bpmn.export_to_writer(&mut f).unwrap();
105
106 let fout = String::from_utf8_lossy(&f);
107 let _bpmn2 = fout.parse::<BusinessProcessModelAndNotation>();
108
109 println!("{}", String::from_utf8_lossy(&f));
110 }
111
112 #[test]
113 fn sbpmn_export_import() {
114 let fin = fs::read_to_string("testfiles/model.sbpmn").unwrap();
115 let sbpmn = fin
116 .parse::<StochasticBusinessProcessModelAndNotation>()
117 .unwrap();
118
119 let mut f = vec![];
120 sbpmn.export_to_writer(&mut f).unwrap();
121 let fout = String::from_utf8_lossy(&f);
122 let _sbpmn2 = fout.parse::<StochasticBusinessProcessModelAndNotation>().unwrap();
123
124 println!("{}", String::from_utf8_lossy(&f));
125 }
126
127 #[test]
128 fn sbpmn_export_import_or() {
129 let fin = fs::read_to_string("testfiles/and-a-b-xor-c-or.sbpmn").unwrap();
130 let sbpmn = fin
131 .parse::<StochasticBusinessProcessModelAndNotation>()
132 .unwrap();
133
134 let mut f = vec![];
135 sbpmn.export_to_writer(&mut f).unwrap();
136 let fout = String::from_utf8_lossy(&f);
137 let _sbpmn2 = fout.parse::<StochasticBusinessProcessModelAndNotation>().unwrap();
138
139 println!("{}", String::from_utf8_lossy(&f));
140 }
141}