从指定路径加载并解析 TOML 配置文件
(path: &str)
| 76 | impl AppConfig { |
| 77 | /// 从指定路径加载并解析 TOML 配置文件 |
| 78 | pub fn load(path: &str) -> Result<Self, Box<dyn std::error::Error>> { |
| 79 | let content = std::fs::read_to_string(path) |
| 80 | .map_err(|e| format!("无法读取配置文件 '{}': {}", path, e))?; |
| 81 | let config: AppConfig = |
| 82 | toml::from_str(&content).map_err(|e| format!("配置文件解析错误 '{}': {}", path, e))?; |
| 83 | |
| 84 | // 基本校验 |
| 85 | if config.extensions.range_start > config.extensions.range_end { |
| 86 | return Err(format!( |
| 87 | "分机范围无效: range_start ({}) > range_end ({})", |
| 88 | config.extensions.range_start, config.extensions.range_end |
| 89 | ) |
| 90 | .into()); |
| 91 | } |
| 92 | |
| 93 | if config.media.rtp_port_start > config.media.rtp_port_end { |
| 94 | return Err(format!( |
| 95 | "RTP 端口范围无效: rtp_port_start ({}) > rtp_port_end ({})", |
| 96 | config.media.rtp_port_start, config.media.rtp_port_end |
| 97 | ) |
| 98 | .into()); |
| 99 | } |
| 100 | |
| 101 | if config.media.rtp_port_start % 2 != 0 { |
| 102 | return Err("RTP 端口起始必须为偶数(RTP 使用偶数端口,RTCP 使用奇数端口)".into()); |
| 103 | } |
| 104 | |
| 105 | if config.media.media_addr.trim().is_empty() { |
| 106 | return Err("media_addr 不能为空。请填写客户端可访问的服务器公网或内网 IP,否则接听后可能无声。".into()); |
| 107 | } |
| 108 | |
| 109 | if config.media.media_addr.parse::<std::net::IpAddr>().is_err() { |
| 110 | return Err(format!( |
| 111 | "media_addr '{}' 不是有效 IP。请填写 Bria、Linkvil 等客户端可访问的公网或内网 IP。", |
| 112 | config.media.media_addr |
| 113 | ) |
| 114 | .into()); |
| 115 | } |
| 116 | |
| 117 | // 校验独立密码中的分机号是否在范围内 |
| 118 | for (ext_str, _) in &config.passwords { |
| 119 | if let Ok(ext_num) = ext_str.parse::<u32>() { |
| 120 | if ext_num < config.extensions.range_start || ext_num > config.extensions.range_end |
| 121 | { |
| 122 | tracing::warn!( |
| 123 | "密码配置中的分机 {} 不在有效范围 {}-{} 内,将被忽略", |
| 124 | ext_str, |
| 125 | config.extensions.range_start, |
| 126 | config.extensions.range_end |
| 127 | ); |
| 128 | } |
| 129 | } else { |
| 130 | return Err( |
| 131 | format!("密码配置中的分机号 '{}' 格式无效(应为数字)", ext_str).into(), |
| 132 | ); |
| 133 | } |
| 134 | } |
| 135 |
nothing calls this directly
no outgoing calls
no test coverage detected