Skip to main content

rust_web_server/entry_point/config_file/
mod.rs

1use std::{io};
2use std::collections::HashMap;
3use std::io::{BufRead, Cursor};
4use crate::entry_point::command_line_args::{CommandLineArgument};
5use file_ext::FileExt;
6use crate::symbol::SYMBOL;
7
8pub fn read_config_file(
9    cursor: Cursor<&[u8]>,
10    mut prefix: String) -> Result<bool, String> {
11
12    let mut argument_list : Vec<String> = vec![];
13    // Tracks how many times each array-table section name has appeared.
14    let mut array_table_counters: HashMap<String, usize> = HashMap::new();
15
16    let lines = cursor.lines().into_iter();
17    for boxed_line in lines {
18        let line = boxed_line.unwrap();
19        let without_comment = strip_comment(line);
20        let without_whitespaces = strip_whitespaces(without_comment.to_string());
21
22        // [[section]] — array table: each occurrence gets a unique numbered prefix.
23        let is_array_table = without_whitespaces.starts_with("[[")
24            && without_whitespaces.ends_with("]]");
25        if is_array_table {
26            let name = without_whitespaces
27                .trim_start_matches('[')
28                .trim_end_matches(']')
29                .to_string();
30            let count = array_table_counters.entry(name.clone()).or_insert(0);
31            prefix = format!("{}_{}", name, count);
32            *count += 1;
33            continue;
34        }
35
36        // [section] — regular table: plain prefix, unchanged behaviour.
37        let is_table = without_whitespaces.starts_with(SYMBOL.opening_square_bracket);
38        if is_table {
39            prefix = without_whitespaces
40                .replace(SYMBOL.opening_square_bracket, SYMBOL.empty_string)
41                .replace(SYMBOL.closing_square_bracket, SYMBOL.empty_string)
42                .to_string();
43        }
44
45        let boxed_split = without_whitespaces.split_once(SYMBOL.equals);
46        if boxed_split.is_none() { // empty line as an example
47            continue;
48        }
49
50        let arg: String;
51        let (unparsed_key, unparsed_value) = boxed_split.unwrap();
52        let value = unparsed_value
53            .replace(SYMBOL.single_quote, SYMBOL.empty_string)
54            .replace(SYMBOL.quotation_mark, SYMBOL.empty_string)
55            .replace(SYMBOL.closing_square_bracket, SYMBOL.empty_string)
56            .replace(SYMBOL.opening_square_bracket, SYMBOL.empty_string);
57        let key = unparsed_key
58            .replace(SYMBOL.underscore, SYMBOL.hyphen);
59
60
61        if prefix.chars().count() == 0 {
62            arg = [
63                SYMBOL.hyphen,
64                SYMBOL.hyphen,
65                &key,
66                SYMBOL.equals,
67                &value
68            ].join("");
69        } else {
70            arg = [
71                SYMBOL.hyphen,
72                SYMBOL.hyphen,
73                &prefix.to_string(),
74                SYMBOL.hyphen,
75                &key,
76                SYMBOL.equals,
77                &value].join("");
78        }
79
80        argument_list.push(arg);
81    }
82    let params = CommandLineArgument::get_command_line_arg_list();
83    CommandLineArgument::_parse(argument_list, params);
84
85    Ok(true)
86}
87
88fn strip_comment(line: String) -> String {
89    let boxed_split = line.split_once(SYMBOL.number_sign);
90    if boxed_split.is_none() {
91        return line;
92    }
93
94    let (without_comment, _) = boxed_split.unwrap();
95
96    without_comment.trim().to_string()
97}
98
99fn strip_whitespaces(line: String) -> String {
100    let without_whitespaces = line.replace(SYMBOL.whitespace, SYMBOL.empty_string);
101
102    without_whitespaces
103}
104
105pub fn override_environment_variables_from_config(filepath: Option<&str>) {
106    println!("\n  Start of Config Section");
107
108    let path: &str;
109    if filepath.is_none() {
110        path = "/rws.config.toml";
111    } else {
112        path = filepath.unwrap();
113    }
114
115    let boxed_static_filepath = FileExt::get_static_filepath(path);
116    if boxed_static_filepath.is_err() {
117        eprintln!("{}", boxed_static_filepath.err().unwrap());
118        return;
119    }
120
121    let static_filepath = boxed_static_filepath.unwrap();
122    let boxed_content = std::fs::read_to_string(static_filepath);
123
124    if boxed_content.is_err() {
125        eprintln!("    Unable to parse rws.config.toml: {}", boxed_content.err().unwrap());
126        println!("  End of Config Section");
127        return;
128    } else {
129        let content = boxed_content.unwrap();
130        let cursor = io::Cursor::new(content.as_bytes());
131        let _ = read_config_file(cursor, SYMBOL.empty_string.to_string());
132    }
133
134    println!("  End of Config Section");
135}