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::parse::model_from_json;
9
use 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.
21
51
pub fn get_example_model(filename: &str) -> Result<Model, anyhow::Error> {
22
    // define relative path -> integration tests dir
23
51
    let base_dir = get_project_root()?;
24
51
    let mut essence_path = PathBuf::new();
25

            
26
    // walk through directory tree recursively starting at base
27
180727
    for entry in WalkDir::new(base_dir).into_iter().filter_map(|e| e.ok()) {
28
180727
        let path = entry.path();
29
180727
        if path.is_file()
30
155023
            && path
31
155023
                .extension()
32
155023
                .map_or(false, |e| e == "essence" || e == "eprime")
33
1768
            && path.file_stem() == Some(std::ffi::OsStr::new(filename))
34
        {
35
34
            essence_path = path.to_path_buf();
36
34
            break;
37
180693
        }
38
    }
39

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

            
42
    // return error if file not found
43
51
    if essence_path.as_os_str().is_empty() {
44
17
        return Err(anyhow::Error::new(std::io::Error::new(
45
17
            std::io::ErrorKind::NotFound,
46
17
            "ERROR: File not found in any subdirectory",
47
17
        )));
48
34
    }
49
34

            
50
34
    // let path = PathBuf::from(format!("../tests/integration/basic/comprehension{}.essence", filename));
51
34
    let mut cmd = std::process::Command::new("conjure");
52
34
    let output = cmd
53
34
        .arg("pretty")
54
34
        .arg("--output-format=astjson")
55
34
        .arg(essence_path)
56
34
        .output()?;
57

            
58
    // convert Conjure's stdout from bytes to string
59
34
    let astjson = String::from_utf8(output.stdout)?;
60

            
61
    //println!("ASTJSON: {}", astjson);
62

            
63
    // parse AST JSON from desired Model format
64
34
    let generated_mdl = model_from_json(&astjson, Default::default())?;
65

            
66
34
    Ok(generated_mdl)
67
51
}
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
79
34
pub fn get_example_model_by_path(filepath: &str) -> Result<Model, anyhow::Error> {
80
34
    let essence_path = PathBuf::from(filepath);
81
34

            
82
34
    // return error if file not found
83
34
    if essence_path.as_os_str().is_empty() {
84
17
        return Err(anyhow::Error::new(std::io::Error::new(
85
17
            std::io::ErrorKind::NotFound,
86
17
            "ERROR: File not found in any subdirectory",
87
17
        )));
88
17
    }
89
17

            
90
17
    // println!("PATH TO FILE: {}", essence_path.display());
91
17

            
92
17
    // Command execution using 'conjure' CLI tool with provided path
93
17
    let mut cmd = std::process::Command::new("conjure");
94
17
    let output = cmd
95
17
        .arg("pretty")
96
17
        .arg("--output-format=astjson")
97
17
        .arg(&essence_path)
98
17
        .output()?;
99

            
100
    // convert Conjure's stdout from bytes to string
101
17
    let astjson = String::from_utf8(output.stdout)?;
102

            
103
    // println!("ASTJSON: {}", astjson);
104

            
105
    // parse AST JSON into the desired Model format
106
17
    let generated_model = model_from_json(&astjson, Default::default())?;
107

            
108
17
    Ok(generated_model)
109
34
}