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

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

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

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

            
45
16662
    let parsed_model = model_from_json(&astjson, context)
46
16662
        .map_err(|e| Box::new(ParseErrorCollection::fatal(e.into())))?;
47
16628
    debug_assert_model_well_formed(&parsed_model, "via-conjure");
48
16628
    Ok(parsed_model)
49
17770
}