Files
yaoayanui/src-tauri/src/agent_id.rs
fengchuanhn@gmail.com 1368db488f 1
2026-05-22 18:09:09 +08:00

116 lines
3.1 KiB
Rust

//! 从应用目录 `resources/data/agent` 读取代理编号。
use std::path::{Path, PathBuf};
use serde_json::Value;
use tauri::{AppHandle, Manager, path::BaseDirectory};
/// 相对可执行文件目录的代理配置路径:`resources/data/agent`。
pub const AGENT_RESOURCE_RELATIVE: &[&str] = &["resources", "data", "agent"];
/// 开发时源码树中的代理配置路径。
pub const AGENT_DEV_RELATIVE: &str = "src-tauri/resources/data/agent";
pub fn read_agent_id_file(path: &Path) -> Option<i64> {
let content = std::fs::read_to_string(path).ok()?;
parse_agent_id_content(&content)
}
/// 解析代理配置文件路径(打包资源 → 应用目录 → 开发目录)。
pub fn resolve_agent_id_path(handle: &AppHandle) -> Option<PathBuf> {
if let Ok(path) = handle.path().resolve("data/agent", BaseDirectory::Resource) {
if path.is_file() {
return Some(path);
}
}
locate_agent_id_file()
}
/// 读取当前应用的代理编号;无配置文件时返回 `None`。
pub fn load_agent_id(handle: &AppHandle) -> Option<i64> {
resolve_agent_id_path(handle).and_then(|path| read_agent_id_file(&path))
}
/// 按可执行文件旁 `resources/data/agent` 或开发目录定位配置文件。
pub fn locate_agent_id_file() -> Option<PathBuf> {
if let Ok(path) = std::env::var("AICLIENT_AGENT_FILE") {
let custom = PathBuf::from(path);
if custom.is_file() {
return Some(custom);
}
}
if let Ok(exe) = std::env::current_exe() {
if let Some(dir) = exe.parent() {
let bundled = dir.join(path_from_parts(AGENT_RESOURCE_RELATIVE));
if bundled.is_file() {
return Some(bundled);
}
}
}
let dev = PathBuf::from(AGENT_DEV_RELATIVE);
if dev.is_file() {
return Some(dev);
}
None
}
fn path_from_parts(parts: &[&str]) -> PathBuf {
let mut path = PathBuf::new();
for part in parts {
path.push(part);
}
path
}
fn parse_agent_id_content(content: &str) -> Option<i64> {
let trimmed = content.trim();
if trimmed.is_empty() {
return None;
}
if let Ok(value) = serde_json::from_str::<Value>(trimmed) {
if let Some(id) = value.get("agent_id").and_then(|v| v.as_i64()) {
if id >= 1 {
return Some(id);
}
}
if let Some(id) = value.as_i64() {
if id >= 1 {
return Some(id);
}
}
}
let first_line = trimmed.lines().next()?.trim();
let id: i64 = first_line.parse().ok()?;
if id >= 1 {
Some(id)
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_integer_line() {
assert_eq!(parse_agent_id_content("5\n"), Some(5));
}
#[test]
fn parse_json_object() {
assert_eq!(parse_agent_id_content(r#"{"agent_id":7}"#), Some(7));
}
#[test]
fn invalid_returns_none() {
assert_eq!(parse_agent_id_content("abc"), None);
assert_eq!(parse_agent_id_content(""), None);
}
}