1
// example_models with get_example_model function
2

            
3
use std::path::PathBuf;
4

            
5
use project_root::get_project_root;
6
use walkdir::WalkDir;
7

            
8
use crate::Model;
9
use crate::parse::model_from_json;
10

            
11
/// Searches recursively in `test-suite/tests/exhaustive` 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.
21
58
pub fn get_example_model(filename: &str) -> Result<Model, anyhow::Error> {
22
    // define relative path -> exhaustive tests dir
23
58
    let base_dir = get_project_root()?.join("test-suite/tests/exhaustive");
24
58
    let mut essence_path = PathBuf::new();
25

            
26
    // walk through directory tree recursively starting at base
27
58
    for entry in WalkDir::new(base_dir)
28
58
        .sort_by_file_name()
29
58
        .into_iter()
30
2679049
        .filter_map(|e| e.ok())
31
    {
32
2679049
        let path = entry.path();
33
2679049
        if path.is_file()
34
2656168
            && path
35
2656168
                .extension()
36
2656023
                .is_some_and(|e| e == "essence" || e == "eprime")
37
20648
            && path.file_stem() == Some(std::ffi::OsStr::new(filename))
38
        {
39
29
            essence_path = path.to_path_buf();
40
29
            break;
41
2679020
        }
42
    }
43

            
44
    //println!("PATH TO FILE: {}", essence_path.display());
45

            
46
    // return error if file not found
47
58
    if essence_path.as_os_str().is_empty() {
48
29
        return Err(anyhow::Error::new(std::io::Error::new(
49
29
            std::io::ErrorKind::NotFound,
50
29
            "ERROR: File not found in any subdirectory",
51
29
        )));
52
29
    }
53

            
54
    // let path = PathBuf::from(format!("../tests/exhaustive/basic/comprehension{}.essence", filename));
55
29
    let mut cmd = std::process::Command::new("conjure");
56
29
    let output = cmd
57
29
        .arg("pretty")
58
29
        .arg("--output-format=astjson")
59
29
        .arg(essence_path)
60
29
        .output()?;
61

            
62
    // convert Conjure's stdout from bytes to string
63
29
    let astjson = String::from_utf8(output.stdout)?;
64

            
65
    //println!("ASTJSON: {}", astjson);
66

            
67
    // parse AST JSON from desired Model format
68
29
    let generated_mdl = model_from_json(&astjson, Default::default())?;
69

            
70
29
    Ok(generated_mdl)
71
58
}
72

            
73
/// Searches for an `.essence` file at the given filepath,
74
/// then uses conjure to process it into astjson, and returns the parsed model.
75
///
76
/// # Arguments
77
///
78
/// * `filepath` - A string slice that holds the full file path
79
///
80
/// # Returns
81
///
82
/// Function returns a `Result<Value, anyhow::Error>`, where `Value` is the parsed model
83
58
pub fn get_example_model_by_path(filepath: &str) -> Result<Model, anyhow::Error> {
84
58
    let essence_path = PathBuf::from(filepath);
85

            
86
    // return error if file not found
87
58
    if essence_path.as_os_str().is_empty() {
88
29
        return Err(anyhow::Error::new(std::io::Error::new(
89
29
            std::io::ErrorKind::NotFound,
90
29
            "ERROR: File not found in any subdirectory",
91
29
        )));
92
29
    }
93

            
94
    // println!("PATH TO FILE: {}", essence_path.display());
95

            
96
    // Command execution using 'conjure' CLI tool with provided path
97
29
    let mut cmd = std::process::Command::new("conjure");
98
29
    let output = cmd
99
29
        .arg("pretty")
100
29
        .arg("--output-format=astjson")
101
29
        .arg(&essence_path)
102
29
        .output()?;
103

            
104
    // convert Conjure's stdout from bytes to string
105
29
    let astjson = String::from_utf8(output.stdout)?;
106

            
107
    // println!("ASTJSON: {}", astjson);
108

            
109
    // parse AST JSON into the desired Model format
110
29
    let generated_model = model_from_json(&astjson, Default::default())?;
111

            
112
29
    Ok(generated_model)
113
58
}