dotenv_config 0.2.3

parse `env` to config struct for Rust
Documentation


impl {{ name }} {

    // Method to get help messages as a HashMap, where the key is the field name and the 
    // value is a tuple of the default value and help message.
    pub fn get_help() -> std::collections::HashMap<String, (String, Option<String>)> {
        let mut help_map = std::collections::HashMap::new();

        {% for field in fields %}
        // If the field is a custom type, recursively get its help information.
        {% if !contains(["usize", "i16", "i32", "i64", "u16", "u32", "u64", "f32", "f64", "bool", "String"], field.typ) && !field.attr_parse %}
            let nested_help = {{ field.typ }}::get_help();
            for (nested_key, nested_value) in nested_help {
                help_map.insert(nested_key, nested_value);
            }
        {% else %}
            // Handle primitive types
            let key = "{{ field.attr_name }}".to_string();
            let help = {% if field.attr_help.is_empty() %} None {% else %} Some("{{ field.attr_help }}".to_string()) {% endif %};
            let value = ("{{ field.attr_default }}".to_string(), help);
            help_map.insert(key, value);
        {% endif %}
        {% endfor %}
        help_map
    }
    
    pub fn init() -> Result<{{ name }}, &'static str> {
        let mut key: &str;
        {% for field in fields %}
        {% if field.attr_name.is_empty() %}
        key = "{{ uppersnake((name.clone() + "_" + field.name.as_str()).as_str()) }}";
        {% else %}
        key = "{{ field.attr_name }}";
        {% endif %}
        {% if contains(["usize","i16","i32","i64","u16","u32","u64","f32","f64","bool"], field.typ) %}
        let {{ field.name }}: Option<{{ field.typ }}> = match std::env::var(key) {
            Ok(val) => match val.to_lowercase().parse() {
                Ok(v) => Some(v),
                Err(_) => {
                    panic!("EnvConfig: {} except a value of [{{ field.typ }}]", key);
                },
            },
            Err(err) => {
                {% if field.attr_default.is_empty() %}
                Some(Default::default())
                {% else %}
                Some("{{ field.attr_default }}".parse().unwrap())
                {% endif %}
            }
        };
        {% else if field.typ == "String" %}
        let {{ field.name }}: Option<{{ field.typ }}> = match std::env::var(key) {
            Ok(val) => Some(val),
            Err(err) => {
                {% if field.attr_default.is_empty() %}
                Some(Default::default())
                {% else %}
                Some("{{ field.attr_default }}".parse().unwrap())
                {% endif %}
            }
        };
        {% else if field.attr_parse %}
        let {{ field.name }}: Option<{{ field.typ }}> = match std::env::var(key) {
            Ok(val) => match val.parse::<{{ field.typ }}>() {
                Ok(v) => Some(v),
                 Err(_) => {
                    panic!("EnvConfig: {} except a value of [{{ field.typ }}]", key);
                },
            },
            Err(_) => {
                {% if field.attr_default.is_empty() %}
                Default::default().parse::<{{ field.typ }}>().ok()
                {% else %}
                "{{ field.attr_default }}".parse::<{{ field.typ }}>().ok()
                {% endif %}
            }
        };
        {% else %}
        let {{ field.name }}: Option<{{ field.typ }}> = match {{ field.typ }}::init() {
            Ok(v) => Some(v),
            Err(_) => None,
        };
        {% endif %}
        {% endfor %}

        Ok({{ name }} {
            {% for field in fields %}
            {% if field.optional %}
            {{ field.name }}: {{ field.name }},
            {% else %}
            {{ field.name }}: {{ field.name }}.ok_or("Build failed: missing {{ field.name }}")?,
            {% endif %}
            {% endfor %}
        })
    }
}