envl 0.10.1

load .envl and .envlconf
Documentation
use std::collections::HashMap;

use envl_utils::{
    error::{EnvlError, ErrorContext},
    types::Position,
    variable::{Type, Value},
};
use envl_vars::misc::variable::VariableValue;

pub fn parse_var(t: Type, v: VariableValue) -> Result<Value, Box<EnvlError>> {
    match &t {
        Type::Null => {
            return Ok(Value::Null);
        }
        Type::String => {
            if let VariableValue::String(value) = &v {
                return Ok(Value::String(value.clone()));
            }
        }
        Type::Char => {
            if let VariableValue::Char(c) = &v {
                return Ok(Value::Char(*c));
            }
        }
        Type::Float => {
            if let VariableValue::Number(n) = &v {
                if let Ok(f) = n.parse::<f64>() {
                    return Ok(Value::Float(f));
                }
            }
        }
        Type::Int => {
            if let VariableValue::Number(n) = &v {
                if let Ok(i) = n.parse::<i64>() {
                    return Ok(Value::Int(i));
                }
            }
        }
        Type::Uint => {
            if let VariableValue::Number(n) = &v {
                if let Ok(u) = n.parse::<u64>() {
                    return Ok(Value::Uint(u));
                }
            }
        }
        Type::Bool => {
            if let VariableValue::Bool(b) = &v {
                return Ok(Value::Bool(b.to_owned()));
            }
        }
        Type::Option(t) => {
            return match parse_var(*t.to_owned(), v) {
                Ok(value) => Ok(value),
                Err(err) => Err(err),
            };
        }
        Type::Array(boxed_type) => {
            if let VariableValue::Array(elements) = &v {
                let element_type = *boxed_type.clone();
                let mut results = Vec::new();

                for element in elements {
                    match parse_var(element_type.clone(), element.clone()) {
                        Ok(e) => {
                            results.push(e);
                        }
                        Err(err) => {
                            return Err(err);
                        }
                    }
                }

                return Ok(Value::Array(results));
            }
        }
        Type::Struct(elements) => {
            if let VariableValue::Struct(vars) = &v {
                let mut hm = HashMap::new();

                for (name, value) in vars {
                    if let Some(t) = elements.get(name) {
                        match parse_var(t.clone(), value.clone()) {
                            Ok(r) => {
                                hm.insert(name.clone(), r);
                            }
                            Err(err) => {
                                return Err(err);
                            }
                        }
                    } else {
                        return Err(Box::from(EnvlError {
                            message: ErrorContext::TranspileError("Invalid type".to_string()),
                            position: Position {
                                file_path: file!().to_string(),
                                row: line!() as usize,
                                col: column!() as usize,
                            },
                        }));
                    }
                }

                return Ok(Value::Struct(hm));
            }
        }
    }

    Err(Box::from(EnvlError {
        message: ErrorContext::TranspileError("Invalid type".to_string()),
        position: Position {
            file_path: file!().to_string(),
            row: line!() as usize,
            col: column!() as usize,
        },
    }))
}