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 %}
})
}
}