1
use crate::errors::{FatalParseError, ParseErrorCollection};
2
use conjure_cp_core::parse::model_from_json;
3
use conjure_cp_core::{Model, context::Context};
4
use std::sync::{Arc, RwLock};
5

            
6
7106
pub fn parse_essence_file(
7
7106
    path: &str,
8
7106
    context: Arc<RwLock<Context<'static>>>,
9
7106
) -> Result<Model, Box<ParseErrorCollection>> {
10
7106
    let mut cmd = std::process::Command::new("conjure");
11
7106
    let output = match cmd
12
7106
        .arg("pretty")
13
7106
        .arg("--output-format=astjson")
14
7106
        .arg(path)
15
7106
        .output()
16
    {
17
7106
        Ok(output) => output,
18
        Err(e) => {
19
            return Err(Box::new(ParseErrorCollection::fatal(
20
                FatalParseError::ConjurePrettyError(e.to_string()),
21
            )));
22
        }
23
    };
24

            
25
7106
    if !output.status.success() {
26
44
        let stderr_string = String::from_utf8(output.stderr)
27
44
            .unwrap_or("stderr is not a valid UTF-8 string".to_string());
28
44
        return Err(Box::new(ParseErrorCollection::fatal(
29
44
            FatalParseError::ConjurePrettyError(stderr_string),
30
44
        )));
31
7062
    }
32

            
33
7062
    let astjson = match String::from_utf8(output.stdout) {
34
7062
        Ok(astjson) => astjson,
35
        Err(e) => {
36
            return Err(Box::new(ParseErrorCollection::fatal(
37
                FatalParseError::ConjurePrettyError(format!(
38
                    "Error parsing output from conjure: {e:#?}"
39
                )),
40
            )));
41
        }
42
    };
43

            
44
7062
    let parsed_model = model_from_json(&astjson, context)
45
7062
        .map_err(|e| Box::new(ParseErrorCollection::fatal(e.into())))?;
46
7062
    Ok(parsed_model)
47
7106
}