cmtool_assemble/parser/
mod.rs1pub mod generated_domain {
4 #![allow(clippy::all)]
5 #![allow(dead_code)]
6 #![allow(unused_imports)]
7 include!(concat!(env!("OUT_DIR"), "/generated_domain.rs"));
8}
9
10use crate::{CMError, DomainData};
13mod reactors;
14use reactors::{parse_connection, parse_feed, parse_reactor};
15mod pfr_mb;
16use crate::ConnectionType;
17pub(super) use pfr_mb::PfrGlobalMassBalance;
18
19const EXPECTED_VERSION: i32 = 3;
21
22pub fn parse_domain(
23 root: &generated_domain::RootElementType,
24) -> Result<(DomainData, PfrGlobalMassBalance, Option<ConnectionType>), CMError> {
25 if root.reactors.content.is_empty() {
26 return Err(CMError::Parse(serde_xml_rs::Error::Custom(
27 "At least one reactor required".to_owned(),
28 )));
29 }
30
31 let info = parse_reactor(&root.reactors)?;
32
33 let mut mass_balance = PfrGlobalMassBalance::new(&info.pfr_names);
34
35 let raw_connections = root
36 .connections
37 .as_ref()
38 .map(|connections| parse_connection(&info, connections, &mut mass_balance))
39 .transpose()?;
40
41 let mut pfeeds = None;
42 if let Some(feeds) = &root.feeds {
43 pfeeds = parse_feed(&info, feeds, &mut mass_balance)?;
44 }
45 mass_balance.validate()?;
46 let run_id = root.run_id.clone();
47 Ok((
48 DomainData {
49 info,
50 feeds: pfeeds,
51 case_path: String::new(),
52 run_id,
53 },
54 mass_balance,
55 raw_connections,
56 ))
57}
58
59pub fn get_root(content: &str) -> Result<generated_domain::Root, CMError> {
60 let root = serde_xml_rs::from_str::<generated_domain::Root>(content)?;
61 eprintln!("WARNING: Some reactor may miss if xml is not parsed correctly");
62 if root.version != EXPECTED_VERSION {
63 return Err(CMError::Custom(format!(
64 "Root version {} is not supported, expected {}",
65 root.version, EXPECTED_VERSION
66 )));
67 }
68 Ok(root)
69}