conjure_core/parse/
example_models.rs

1// example_models with get_example_model function
2
3use std::path::PathBuf;
4
5use project_root::get_project_root;
6use walkdir::WalkDir;
7
8use crate::parse::model_from_json;
9use crate::Model;
10
11/// Searches recursively in `../tests/integration` folder for an `.essence` file matching the given
12/// filename, then uses conjure to process it into astjson, and returns the parsed model.
13///
14/// # Arguments
15///
16/// * `filename` - A string slice that holds filename without extension
17///
18/// # Returns
19///
20/// Function returns a `Result<Value, anyhow::Error>`, where `Value` is the parsed model.
21pub fn get_example_model(filename: &str) -> Result<Model, anyhow::Error> {
22    // define relative path -> integration tests dir
23    let base_dir = get_project_root()?;
24    let mut essence_path = PathBuf::new();
25
26    // walk through directory tree recursively starting at base
27    for entry in WalkDir::new(base_dir).into_iter().filter_map(|e| e.ok()) {
28        let path = entry.path();
29        if path.is_file()
30            && path
31                .extension()
32                .is_some_and(|e| e == "essence" || e == "eprime")
33            && path.file_stem() == Some(std::ffi::OsStr::new(filename))
34        {
35            essence_path = path.to_path_buf();
36            break;
37        }
38    }
39
40    //println!("PATH TO FILE: {}", essence_path.display());
41
42    // return error if file not found
43    if essence_path.as_os_str().is_empty() {
44        return Err(anyhow::Error::new(std::io::Error::new(
45            std::io::ErrorKind::NotFound,
46            "ERROR: File not found in any subdirectory",
47        )));
48    }
49
50    // let path = PathBuf::from(format!("../tests/integration/basic/comprehension{}.essence", filename));
51    let mut cmd = std::process::Command::new("conjure");
52    let output = cmd
53        .arg("pretty")
54        .arg("--output-format=astjson")
55        .arg(essence_path)
56        .output()?;
57
58    // convert Conjure's stdout from bytes to string
59    let astjson = String::from_utf8(output.stdout)?;
60
61    //println!("ASTJSON: {}", astjson);
62
63    // parse AST JSON from desired Model format
64    let generated_mdl = model_from_json(&astjson, Default::default())?;
65
66    Ok(generated_mdl)
67}
68
69/// Searches for an `.essence` file at the given filepath,
70/// then uses conjure to process it into astjson, and returns the parsed model.
71///
72/// # Arguments
73///
74/// * `filepath` - A string slice that holds the full file path
75///
76/// # Returns
77///
78/// Function returns a `Result<Value, anyhow::Error>`, where `Value` is the parsed model
79pub fn get_example_model_by_path(filepath: &str) -> Result<Model, anyhow::Error> {
80    let essence_path = PathBuf::from(filepath);
81
82    // return error if file not found
83    if essence_path.as_os_str().is_empty() {
84        return Err(anyhow::Error::new(std::io::Error::new(
85            std::io::ErrorKind::NotFound,
86            "ERROR: File not found in any subdirectory",
87        )));
88    }
89
90    // println!("PATH TO FILE: {}", essence_path.display());
91
92    // Command execution using 'conjure' CLI tool with provided path
93    let mut cmd = std::process::Command::new("conjure");
94    let output = cmd
95        .arg("pretty")
96        .arg("--output-format=astjson")
97        .arg(&essence_path)
98        .output()?;
99
100    // convert Conjure's stdout from bytes to string
101    let astjson = String::from_utf8(output.stdout)?;
102
103    // println!("ASTJSON: {}", astjson);
104
105    // parse AST JSON into the desired Model format
106    let generated_model = model_from_json(&astjson, Default::default())?;
107
108    Ok(generated_model)
109}