Skip to main content

crypt_configs/
lib.rs

1//! Crypt Config Parser
2//! Created 6/2/2026 - Nyx
3
4use std::path::Path;
5
6use crate::{body::CryptConfig, lexer::{create_registry, lex_file}, parse::{ParseError, Parser, parse_expression}, resolve::resolve};
7
8// MODULES
9mod lexer;
10mod parse;
11pub mod body;
12mod resolve;
13
14
15/// Opens a crypt config file and builds it into a crypt config object.
16/// 
17/// See [CryptConfig] for more information on how to handle the data parsed.
18/// 
19/// # Example
20/// 
21/// ```
22/// use crypt_configs::open_config;
23/// 
24/// let _config = open_config("tests/test.crypt").expect("Failed to open config!");
25/// ```
26pub fn open_config<P>(path: P) -> Result<CryptConfig, ParseError> 
27where 
28    P: AsRef<Path>
29{
30    let reg = create_registry();
31
32    let tokens = lex_file(path, &reg)?;
33
34    let parser = &mut Parser::new(tokens);
35    let ast = parse_expression(parser, 0)?;
36
37    let mut config = CryptConfig::new();
38    resolve(&mut config, *ast);
39    Ok(config)
40}
41
42
43#[cfg(test)]
44mod config_tests {
45    use crate::open_config;
46
47
48    #[test]
49    fn basic_file_test() {
50        let config = open_config("tests/test.crypt").expect("failed to open config file");
51
52        let version = config.get("version")
53            .expect("no version provided!")
54            .expect_string("expected version to be a string literal");
55        assert_eq!(version, "0.1.0");
56
57        let version = config.get("name")
58            .expect("no name provided!")
59            .expect_string("expected name to be a string literal");
60        assert_eq!(version, "Test");
61
62        let version = config.get("type")
63            .expect("no type provided!")
64            .expect_string("expected type to be a string literal");
65        assert_eq!(version, "Executable");
66    }
67
68    #[test]
69    fn complex_file_test() {
70        let config = open_config("tests/nesting.crypt").expect("failed to open config file");
71
72        let root = config.get("root")
73            .expect("no root object found!")
74            .expect_nested_config("root isn't a config");
75
76        let inner_1 = root.get("inner_1")
77            .expect("no object named inner_1!")
78            .expect_nested_config("inner_1 isn't a config");
79
80        let inner_2 = root.get("inner_2")
81            .expect("no object named inner_2!")
82            .expect_nested_config("inner_2 isn't a config");
83
84        let inner_1_contents = inner_1.get("content")
85            .expect("inner_1 doesn't have any content")
86            .expect_string("inner_1 content isn't a string");
87
88        let inner_2_contents = inner_2.get("content")
89            .expect("inner_2 doesn't have any content")
90            .expect_string("inner_2 content isn't a string");
91                
92        assert_eq!(inner_1_contents, "Contents of inner 1");
93        assert_eq!(inner_2_contents, "Contents of inner 2");
94    }
95
96}