use std::env;
use std::error::Error;
use std::fs;
use std::path::PathBuf;
use super::IBusErr;
pub fn get_ibus_addr() -> Result<String, Box<dyn Error>> {
if let Ok(address) = env::var("IBUS_ADDRESS") {
return Ok(address);
}
let ibus_address_file = match env::var("IBUS_ADDRESS_FILE") {
Ok(path) => PathBuf::from(path),
Err(_) => {
let config_home: PathBuf = match env::var("XDG_CONFIG_HOME") {
Ok(home) => PathBuf::from(home),
Err(_) => PathBuf::from(env::var("HOME")?).join(".config"),
};
let x_display;
let wayland_display;
let (hostname, display) = match env::var("WAYLAND_DISPLAY") {
Ok(display) => {
wayland_display = display;
("unix", wayland_display.as_str())
}
Err(_) => {
x_display = env::var("DISPLAY")?;
let mut parts = x_display.split(&[':', '.']);
let hostname = parts.next().ok_or("DISPLAY env var is empty")?;
let display = parts.next().ok_or("DISPLAY env var has no colon")?;
(
if hostname.is_empty() {
"unix"
} else {
hostname
},
display,
)
}
};
let machine_id_file_content = std::fs::read_to_string("/var/lib/dbus/machine-id")
.or(std::fs::read_to_string("/etc/machine-id"))
.map_err(|e| IBusErr::new(format!("reading /etc/machine-id: {e}")))?;
let machine_id = machine_id_file_content.trim();
config_home
.join("ibus/bus")
.join(format!("{machine_id}-{hostname}-{display}"))
}
};
let 地址 = fs::read_to_string(&ibus_address_file)?
.lines()
.filter(|i| !i.starts_with("#"))
.find_map(|i| i.strip_prefix("IBUS_ADDRESS=").map(|i| i.to_string()))
.ok_or(IBusErr::new(format!(
"can not find ibus addr in: {}",
ibus_address_file.display()
)))?;
Ok(地址.to_string())
}