ruwebframe 0.1.7

a simple webframe for rust actix-web, based on rudi and rbatis.
Documentation
use crate::rubase::ruenc;
use crate::rulog::ru_log;
use heck::{ToLowerCamelCase, ToSnakeCase};
use yimi_rutool::core::StrUtil;

use crate::rubase::rutils::str_utils;
use std::collections::HashMap;
use std::env;

pub trait IsEmptyString {
    fn is_empty(&self) -> bool;
}

impl IsEmptyString for Option<String> {
    fn is_empty(&self) -> bool {
        return match self {
            Some(s) => s.is_empty(),
            _ => true,
        };
    }
}

impl IsEmptyString for Option<&str> {
    fn is_empty(&self) -> bool {
        return match self {
            Some(s) => s.is_empty(),
            _ => true,
        };
    }
}
pub fn capitalize(s: &str) -> String {
    let mut c = s.chars();

    match c.next() {
        Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
        None => String::new(),
    }
}
pub fn exist_enc(var: &str) -> bool {
    var.contains("enc(")
}
pub fn exist_env(var: &str) -> bool {
    var.contains("${")
}
pub fn parse_env_var(var: String) -> String {
    let mut ret = parse_env_var_only(var);
     dec_var_enc(ret)
}

pub fn parse_env_var_only(var: String) -> String {
    if !exist_env(var.as_str()) {
        return var;
    }
    // 去掉 ${ 和 }
    let inner = var.trim().trim_start_matches("${").trim_end_matches("}");
    let words = StrUtil::split(inner, ":");
    if words.len() > 1 {
        return words[1].to_string();
    }
    words[0].to_string()
}
pub fn dec_var_enc(var: String) -> String {
    if exist_enc(var.as_str()) {
        let v = var.replace("enc(", "").replace(")", "");
        let ret = ruenc::find_bean_ru_enc().unwrap().dec(&v);
        return ret;
    }

    return var;
}

pub fn to_snake_case(p: &str) -> String {
    p.to_snake_case().to_string()
}
pub fn to_camel_case(p: &str) -> String {
    p.to_lower_camel_case().to_string()
}

pub fn expand_env_var(input: &str) -> String {
    if !input.contains("${") {
        return input.to_string();
    }
    let env_map: HashMap<String, String> = env::vars().collect();
    // let expanded =  strutils::expand_env_vars(input, &env_map);
    if env_map.len() > 0 {
        return env_map.values().take(1).next().unwrap().to_string();
    }
    return "".to_string();
}
/// 解析形如 ${VAR:default} 或 $VAR 或 ${VAR} 的环境变量引用
/// 支持嵌套(但这里为了简洁,只做单层替换)
pub fn expand_env_vars(input: &str, env_map: &HashMap<String, String>) -> String {
    let mut result = String::new();
    let chars: Vec<char> = input.chars().collect();
    let mut i = 0;

    while i < chars.len() {
        if chars[i] == '$' && i + 1 < chars.len() {
            // 处理 ${VAR:default} 或 ${VAR}
            if chars[i + 1] == '{' {
                let start = i + 2;
                let mut end = start;
                let mut depth = 1;
                while end < chars.len() && depth > 0 {
                    if chars[end] == '{' {
                        depth += 1;
                    } else if chars[end] == '}' {
                        depth -= 1;
                    }
                    end += 1;
                }
                let var_expr = &chars[start..end - 1];
                let var_str: String = var_expr.iter().collect();

                // 解析 VAR 和默认值
                let (var_name, default_value) = if let Some(idx) = var_str.find(':') {
                    (var_str[..idx].trim(), Some(var_str[idx + 1..].trim()))
                } else {
                    (var_str.trim(), None)
                };

                // 获取环境变量值
                let value = env_map
                    .get(var_name)
                    .map(|s| s.as_str())
                    .or_else(|| default_value)
                    .unwrap_or("");

                result.push_str(value);
                i = end;
                continue;
            }
            // 处理 $VAR (简单形式)
            else if chars[i + 1].is_alphabetic() || chars[i + 1] == '_' {
                let start = i + 1;
                let mut end = start;
                while end < chars.len() && (chars[end].is_alphanumeric() || chars[end] == '_') {
                    end += 1;
                }
                let var_name: String = chars[start..end].iter().collect();
                let value = env_map.get(&var_name).map(|s| s.as_str()).unwrap_or("");
                result.push_str(value);
                i = end;
                continue;
            }
        }
        result.push(chars[i]);
        i += 1;
    }
    result
}
#[test]
fn main() {
    unsafe {
        env::set_var("DB_DEBUG", "false".to_string());
    }
    // 读取所有环境变量
    let env_map: HashMap<String, String> = env::vars().collect();

    // 测试
    let input = "DB_DEBUG=${DB_DEBUG:true}";
    let expanded = expand_env_vars(input, &env_map);
    println!("{}", expanded); // 如果 DB_DEBUG 未设置,输出 "DB_DEBUG=true"
    dotenvy::dotenv().ok();

    // 或者直接解析单个变量
    let db_debug = env_map
        .get("DB_DEBUG")
        .map(|s| s.as_str())
        .unwrap_or("true");
    println!("DB_DEBUG = {}", db_debug);
}
pub fn str2i32(s: &str) -> i32 {
    s.parse().unwrap_or(0)
}
pub fn str2u16(s: &str) -> u16 {
    str2i32(s) as u16
}