use std::collections::HashMap;
use envl_config::misc::config::Config;
use envl_utils::{
error::{EnvlError, ErrorContext},
types::Position,
variable::{Type, Value as VarVariable},
};
use crate::{
misc::vars::Value,
vars::{type_check::type_check, var::gen_variable_data},
VarData, VariableHashMap,
};
pub mod type_check;
pub mod var;
pub(crate) fn gen_vars(
_var_file_path: String,
vars: HashMap<String, Value>,
config: Config,
) -> Result<VariableHashMap, EnvlError> {
let mut no_used_vars = Vec::new();
let mut hm = HashMap::new();
for (name, var) in config.vars.clone() {
if let Some(value) = vars.get(&name) {
match gen_variable_data(&name, value.clone(), var.v_type.clone()) {
Ok(var_data) => {
hm.insert(
name,
VarData {
value: var_data,
position: value.position.clone(),
v_type: var.v_type,
default_value: var.default_value,
actions_value: var.actions_value,
},
);
}
Err(err) => {
return Err(err);
}
}
} else {
if var.default_value == VarVariable::Null {
match var.v_type {
Type::Option(_) => {}
_ => {
return Err(EnvlError {
message: ErrorContext::Required(name.to_string()),
position: Position::default(),
});
}
}
}
type_check(
&name,
var.default_value.clone(),
var.v_type.clone(),
&var.position,
)?;
hm.insert(
name,
VarData {
value: var.default_value.clone(),
v_type: var.v_type,
default_value: var.default_value,
actions_value: var.actions_value,
position: var.position,
},
);
}
}
for (name, value) in vars {
if !config.vars.contains_key(&name) {
no_used_vars.push((name, value.position));
}
}
if !no_used_vars.is_empty() {
let err_msg = no_used_vars
.iter()
.map(|(n, _)| n.clone())
.collect::<Vec<_>>()
.join(" and ")
.clone();
let file_position = &no_used_vars[0].1;
return Err(EnvlError {
message: ErrorContext::UnnecessaryVariable(err_msg),
position: file_position.clone(),
});
}
Ok(hm)
}