aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib.rs
blob: 91c99ea9b0f516c06981f877e13cf29ea9b98543 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

#[macro_use]
extern crate log;

extern crate toml;
extern crate modelica_parser;

pub mod modelica_model;
pub mod transpile_scheme;
pub mod transpile_js;

use std::path::Path;
use std::fs;
use std::io::Read;
use std::fs::File;

#[derive(Debug, PartialEq)]
pub struct ModelMetadata {
    pub name_en: String,
    pub description_en: Option<String>,
}

#[derive(Debug, PartialEq)]
pub enum ModelVarType {
    Independent,
    Dependent,
    Constant,
    Time,
    State,
    Parameter,
}

#[derive(Debug, PartialEq)]
pub struct ModelVar {
    pub slug: String,
    pub name_en: Option<String>,
    pub vtype: ModelVarType,
    pub latex: Option<String>,
    pub units_si: Option<String>,
}

#[derive(Debug, PartialEq)]
pub struct ModelEntry {
    pub ast: modelica_parser::ModelicaModel,
    pub metadata: ModelMetadata,
    pub markdown: String,
}

pub fn parse_metadata(raw: String) -> Result<ModelMetadata, String> {
    let root = toml::Parser::new(&raw).parse().unwrap();
    let model = root.get("model")
        .expect("missing 'model' section")
        .as_table()
        .unwrap();
    Ok(ModelMetadata {
        name_en: model.get("name-en").unwrap().as_str().unwrap().to_string(),
        description_en: model.get("description-en").map(|x| x.as_str().unwrap().to_string()),
    })
}

pub fn load_model_entry(p: &Path) -> Result<ModelEntry, String> {
    debug!("Attempting to load model from: {:?}", p);

    let ast = {
        let mut s = String::new();
        try!(File::open(p.join("model.modelica"))
            .and_then(|mut f| f.read_to_string(&mut s))
            .map_err(|e| e.to_string()));
        try!(modelica_parser::parse_model(&s).map_err(|e| format!("{:?}", e)))
    };

    let metadata = {
        let mut s = String::new();
        try!(File::open(p.join("metadata.toml"))
            .and_then(|mut f| f.read_to_string(&mut s))
            .map_err(|e| e.to_string()));
        parse_metadata(s).unwrap()
    };

    let markdown = {
        let mut s = String::new();
        try!(File::open(p.join("page.md"))
            .and_then(|mut f| f.read_to_string(&mut s))
            .map_err(|e| e.to_string()));
        s
    };

    Ok(ModelEntry {
        ast: ast,
        metadata: metadata,
        markdown: markdown,
    })
}

pub fn search_models(p: &Path) -> Vec<String> {
    if fs::metadata(p).unwrap().is_dir() {
        fs::read_dir(p)
            .unwrap()
            .map(|x| x.unwrap())
            .filter(|x| x.metadata().unwrap().is_dir())
            .filter(|x| x.path().join("model.modelica").exists())
            .map(|x| x.path().to_string_lossy().to_string())
            .collect()
    } else {
        vec![]
    }
}