use serde::{Deserialize, Serialize}; use std::io::{Read, Write}; use std::os::unix::net::UnixStream; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct HistoryItem { pub content: String, pub timestamp: i64, } #[derive(Serialize, Deserialize, Debug)] pub enum IpcRequest { GetHistory { limit: usize, }, SetClipboard { content: String, }, DeleteEntry { content: String, }, UpdateEntry { old_content: String, new_content: String, }, AddEntry { content: String, }, ClearHistory, } #[derive(Serialize, Deserialize, Debug)] pub enum IpcResponse { History(Vec), Ok, Error(String), } fn send_request(req: &IpcRequest) -> Option { let dir = directories::ProjectDirs::from("com", "zefad", "rklipd")? .data_dir() .to_path_buf(); let mut stream = UnixStream::connect(dir.join("rklip.sock")).ok()?; let json = serde_json::to_string(req).ok()?; stream.write_all(json.as_bytes()).ok()?; stream.shutdown(std::net::Shutdown::Write).ok()?; let mut buf = String::new(); stream.read_to_string(&mut buf).ok()?; serde_json::from_str(&buf).ok() } pub fn fetch_history(limit: usize) -> Option> { match send_request(&IpcRequest::GetHistory { limit })? { IpcResponse::History(items) => Some(items), _ => None, } } pub fn set_clipboard(content: String) -> bool { matches!( send_request(&IpcRequest::SetClipboard { content }), Some(IpcResponse::Ok) ) } pub fn delete_entry(content: String) -> bool { matches!( send_request(&IpcRequest::DeleteEntry { content }), Some(IpcResponse::Ok) ) } pub fn update_entry(old_content: String, new_content: String) -> bool { matches!( send_request(&IpcRequest::UpdateEntry { old_content, new_content }), Some(IpcResponse::Ok) ) } pub fn add_entry(content: String) { let _ = send_request(&IpcRequest::AddEntry { content }); } pub fn clear_history() -> bool { matches!( send_request(&IpcRequest::ClearHistory), Some(IpcResponse::Ok) ) }