use parking_lot::RwLock;
use serde_json::Value;
use std::collections::HashMap;
use std::path::PathBuf;
lazy_static::lazy_static! {
static ref PROPS: RwLock<HashMap<String, Value>> = RwLock::new(HashMap::new());
static ref ROBOT_INFO: RwLock<Option<HashMap<String, Value>>> = RwLock::new(None);
}
pub fn load_props() {
let config_path = get_config_path();
if let Ok(content) = std::fs::read_to_string(&config_path) {
for line in content.lines() {
let line = line.trim();
if line.is_empty() || line.starts_with('#') {
continue;
}
if let Some(idx) = line.find('=') {
let key = line[..idx].trim().to_string();
let value = line[idx + 1..].trim().to_string();
PROPS.write().insert(key, Value::String(value));
}
}
}
}
pub fn get_string(key: &str, default: &str) -> String {
PROPS
.read()
.get(key)
.and_then(|v| v.as_str())
.map(|s| s.to_string())
.unwrap_or_else(|| default.to_string())
}
pub fn get_bool(key: &str, default: bool) -> bool {
PROPS
.read()
.get(key)
.and_then(|v| {
if let Some(b) = v.as_bool() {
Some(b)
} else if let Some(s) = v.as_str() {
s.parse().ok()
} else {
None
}
})
.unwrap_or(default)
}
pub fn get_int(key: &str, default: i64) -> i64 {
PROPS
.read()
.get(key)
.and_then(|v| {
if let Some(n) = v.as_i64() {
Some(n)
} else if let Some(s) = v.as_str() {
s.parse().ok()
} else {
None
}
})
.unwrap_or(default)
}
fn get_config_path() -> PathBuf {
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
home.join(".config")
.join("robomotion")
.join("config.properties")
}
pub async fn get_robot_info_cached() -> crate::runtime::Result<HashMap<String, Value>> {
{
let cached = ROBOT_INFO.read();
if let Some(info) = cached.as_ref() {
return Ok(info.clone());
}
}
let info = crate::runtime::client::get_robot_info_internal().await?;
*ROBOT_INFO.write() = Some(info.clone());
Ok(info)
}
pub async fn get_robot_version() -> crate::runtime::Result<String> {
let info = get_robot_info_cached().await?;
Ok(info
.get("version")
.and_then(|v| v.as_str())
.unwrap_or("0.0.0")
.to_string())
}
pub async fn get_robot_id_cached() -> crate::runtime::Result<String> {
let info = get_robot_info_cached().await?;
Ok(info
.get("id")
.and_then(|v| v.as_str())
.unwrap_or("unknown")
.to_string())
}