Skip to main content

ebi_bpmn/
exporter.rs

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        //XML declaration
20        x.write_event(Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), None)))?;
21
22        //definitions
23        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        //collaboration
35        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            //expanded pools
42            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            //collapsed pools
55            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            //messages
71            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}