//! audit 共享纯 helper：RiskLevel ↔ 字符串转换 + 字符串安全截断。
//!
//! 第五批从 audit/mod.rs 抽离，行为零变更：
//! - `risk_str` / `risk_from_str`：finalize / restore 通过 `super::` 引用（pub(crate)）。
//! - `truncate_chars`：mod.rs 的 process_tool_calls DTO 装配用 + record.rs 审计面板 IPC 用（pub(crate)）。
//!
//! re-export 维持原路径透明：`super::risk_str` / `super::risk_from_str` / `super::truncate_chars`
//! 在 audit/mod.rs 内通过 `pub(crate) use` 引入后裸名可用，外部子模块的 `super::risk_*` 引用不变。

use df_ai::ai_tools::RiskLevel;

/// RiskLevel → 审计记录字符串（low/medium/high）
pub(crate) fn risk_str(r: RiskLevel) -> &'static str {
    match r {
        RiskLevel::Low => "low",
        RiskLevel::Medium => "medium",
        RiskLevel::High => "high",
    }
}

/// 审计记录字符串 → RiskLevel（启动重建 pending_approvals 用，未知串返回 None 跳过）
pub(crate) fn risk_from_str(s: &str) -> Option<RiskLevel> {
    match s {
        "low" => Some(RiskLevel::Low),
        "medium" => Some(RiskLevel::Medium),
        "high" => Some(RiskLevel::High),
        _ => None,
    }
}

/// 截断字符串到 max 字符（按 char_indices 边界切，避免切坏中文/emoji）
pub(crate) fn truncate_chars(s: &str, max: usize) -> String {
    if s.chars().count() <= max {
        return s.to_string();
    }
    let mut out: String = s.chars().take(max).collect();
    out.push('…');
    out
}
