#[macro_use] extern crate log; pub mod modelica_parser; pub mod modelica_ast; use std::path::Path; use std::fs; use std::io::Read; use std::fs::File; #[derive(Debug, PartialEq)] pub struct ModelMetadata { pub slug: String, pub name_en: String, pub description_en: Option, pub vars: Vec, } #[derive(Debug, PartialEq)] pub enum ModelVarType { Independent, Dependent, Constant, } #[derive(Debug, PartialEq)] pub struct ModelVar { pub slug: String, pub name_en: String, pub vtype: Option, pub latex: Option, pub units_si: Option, } #[derive(Debug, PartialEq)] pub struct ModelEntry { pub ast: modelica_ast::ModelicaModel, pub metadata: ModelMetadata, pub markdown: String, } // TODO: this pub fn parse_metadata(s: String) -> Result { Ok(ModelMetadata { slug: "dummy".to_string(), name_en: "Bogus Dummy Model".to_string(), description_en: None, vars: vec![], }) } pub fn load_model_entry(p: &Path) -> Result { 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, }) } // TODO: have this check for model.modelica etc pub fn search_models(p: &Path) -> Vec { if fs::metadata(p).unwrap().is_dir() { fs::read_dir(p).unwrap() .map(|x| x.unwrap()) .filter(|x| x.metadata().unwrap().is_dir()) .map(|x| x.path().to_string_lossy().to_string()) .collect() } else { vec![] } } /* ******************************** Tests ******************************* */ #[test] fn test_parse_metadata() { assert_eq!(parse_metadata("asdf".to_string()).unwrap(), ModelMetadata { slug: "dummy".to_string(), name_en: "Bogus Dummy Model".to_string(), description_en: None, vars: vec![], }); } #[test] fn test_load_model_entry() { load_model_entry(Path::new("./examples/classic_gravitation/")).unwrap(); } #[test] fn test_search_models() { assert_eq!(search_models(Path::new("./examples/")).len() > 1, true); } #[test] fn test_lexical() { assert_eq!(&format!("{:?}", modelica_parser::parse_integer("+123").unwrap()), "123"); assert_eq!(&format!("{:?}", modelica_parser::parse_integer("-9").unwrap()), "-9"); assert_eq!(&format!("{:?}", modelica_parser::parse_float("-1.0e0").unwrap()), "-1"); assert_eq!(&format!("{:?}", modelica_parser::parse_float("123.456").unwrap()), "123.456"); } #[test] fn test_parse() { let example1 = r#"model MinimalModel Real x; equation x = 1; end MinimalModel; "#; assert_eq!(&format!("{:?}", modelica_parser::parse_model(example1).unwrap()), example1); let example2 = r#"model MinimalModel parameter Real a; Real b; equation connect(a, b); a = 1; b = ((abs(a) + 2) / 4); end MinimalModel; "#; assert_eq!(&format!("{:?}", modelica_parser::parse_model(example2).unwrap()), example2); }