Skip to main content

cmtool_assemble/
lib.rs

1// SPDX-License-Identifier: GPL-3.0-or-later
2
3mod data;
4mod errors;
5mod generators;
6mod map_generation;
7mod parser;
8
9pub use crate::data::{DomainData, DomainInfo};
10use crate::parser::{generated_domain::RootElementType, get_root, parse_domain};
11pub use cmtool_data::PhaseCM; //reexport to have easier dependency
12pub use data::{FeedFlow, ParsedFeeds};
13pub use errors::CMError;
14pub use generators::GenerateContract;
15use map_generation::generate_flowmap;
16pub type ConnectionType = [cmtool_data::RawDataFlux; 2];
17
18/// Domain parser
19// TODO: make it private + change name
20pub struct Parser(RootElementType);
21
22impl Parser {
23    /// Create parser from xml content
24    /// Returns id + object if suceeds
25    pub fn start_parsing(reactor_content: &str) -> Result<(String, Self), CMError> {
26        let root = get_root(reactor_content)?;
27        Ok((root.run_id.clone(), Self(root)))
28    }
29
30    /// Parse domain and generate content in the root directory if needed
31    /// Returns info about generated domain if suceeds
32    fn continue_parsing(
33        p: Parser,
34        root_dir: impl AsRef<std::path::Path>,
35    ) -> Result<(DomainData, Option<GenerateContract>), CMError> {
36        let path = root_dir.as_ref().join(&p.0.run_id);
37        Self::continue_parsing_with_path(p, path)
38    }
39
40    /// Parse domain and generate content at given abolute path if needed
41    /// Returns info about generated domain if suceeds
42    pub fn continue_parsing_with_path(
43        Parser(root): Parser,
44        root_dir: impl AsRef<std::path::Path>,
45    ) -> Result<(DomainData, Option<GenerateContract>), CMError> {
46        let (mut domain, mb, connections) = parse_domain(&root)?;
47
48        //TODO: Do not create all, return error if not root_dir
49        // std::fs::create_dir_all(root_path)?;
50        let gc = generate_flowmap(None, &root.reactors, &mb, connections)?;
51        let path = root_dir.as_ref().to_owned();
52
53        domain.case_path = path.as_os_str().to_string_lossy().to_string();
54        Ok((domain, gc))
55    }
56}
57
58//Parse and generate domain at root dir  from give xml content
59// Returns info about domain if suceeds
60pub fn generate_domain(
61    root_dir: impl AsRef<std::path::Path>,
62    reactor_content: &str,
63) -> Result<(DomainData, Option<GenerateContract>), CMError> {
64    let (_id, parser) = Parser::start_parsing(reactor_content)?;
65
66    Parser::continue_parsing(parser, root_dir)
67}
68
69//Parse and generate domain at root dir  from give xml content
70// Returns info about domain if suceeds
71pub fn generate_and_write_domain(
72    root_dir: impl AsRef<std::path::Path>,
73    reactor_content: &str,
74) -> Result<DomainData, CMError> {
75    let (domain, gc) = generate_domain(&root_dir, reactor_content)?;
76    if let Some(contract) = gc {
77        contract.write(root_dir)?;
78    }
79    Ok(domain)
80}
81
82//Parse and generate domain at root dir  from give xml filepath
83// For headless/cli use reads/create folder and generate
84pub fn headless_generate(
85    reactor_input_file_name: &str,
86    path: impl AsRef<std::path::Path>,
87) -> Result<(), CMError> {
88    let contents = std::fs::read_to_string(reactor_input_file_name)?;
89    //Useless because already created in continue_parsing_with_path
90    //TODO: keep it here and returns errors if not exist
91    let root_dir = path.as_ref().to_str().expect("path str").to_owned();
92    std::fs::create_dir_all(&root_dir)?;
93    generate_domain(&root_dir, &contents)?;
94    Ok(())
95}