use std::path::Path;
use crate::{body::CryptConfig, lexer::{create_registry, lex_file}, parse::{ParseError, Parser, parse_expression}, resolve::resolve};
mod lexer;
mod parse;
pub mod body;
mod resolve;
pub fn open_config<P>(path: P) -> Result<CryptConfig, ParseError>
where
P: AsRef<Path>
{
let reg = create_registry();
let tokens = lex_file(path, ®)?;
let parser = &mut Parser::new(tokens);
let ast = parse_expression(parser, 0)?;
let mut config = CryptConfig::new();
resolve(&mut config, *ast);
Ok(config)
}
#[cfg(test)]
mod config_tests {
use crate::open_config;
#[test]
fn basic_file_test() {
let config = open_config("tests/test.crypt").expect("failed to open config file");
let version = config.get("version")
.expect("no version provided!")
.expect_string("expected version to be a string literal");
assert_eq!(version, "0.1.0");
let version = config.get("name")
.expect("no name provided!")
.expect_string("expected name to be a string literal");
assert_eq!(version, "Test");
let version = config.get("type")
.expect("no type provided!")
.expect_string("expected type to be a string literal");
assert_eq!(version, "Executable");
}
#[test]
fn complex_file_test() {
let config = open_config("tests/nesting.crypt").expect("failed to open config file");
let root = config.get("root")
.expect("no root object found!")
.expect_nested_config("root isn't a config");
let inner_1 = root.get("inner_1")
.expect("no object named inner_1!")
.expect_nested_config("inner_1 isn't a config");
let inner_2 = root.get("inner_2")
.expect("no object named inner_2!")
.expect_nested_config("inner_2 isn't a config");
let inner_1_contents = inner_1.get("content")
.expect("inner_1 doesn't have any content")
.expect_string("inner_1 content isn't a string");
let inner_2_contents = inner_2.get("content")
.expect("inner_2 doesn't have any content")
.expect_string("inner_2 content isn't a string");
assert_eq!(inner_1_contents, "Contents of inner 1");
assert_eq!(inner_2_contents, "Contents of inner 2");
}
}