Private
Public Access
1
0
Files
Kordophone/kpcli/src/daemon/xpc.rs

101 lines
3.6 KiB
Rust
Raw Normal View History

2025-08-01 12:26:17 -07:00
#![cfg(target_os = "macos")]
//! macOS XPC implementation of the DaemonInterface for kpcli.
use super::{ConfigCommands, DaemonInterface};
use anyhow::Result;
use async_trait::async_trait;
use futures::stream::StreamExt;
use futures::executor::block_on;
use std::collections::HashMap;
use xpc_connection::{Message, XpcConnection};
const SERVICE_NAME: &str = "net.buzzert.kordophonecd\0";
const GET_VERSION_METHOD: &str = "GetVersion\0";
/// XPC-based implementation of DaemonInterface that sends method calls to the daemon over libxpc.
pub struct XpcDaemonInterface;
impl XpcDaemonInterface {
/// Create a new XpcDaemonInterface. No state is held.
pub fn new() -> Result<Self> {
Ok(Self)
}
}
#[async_trait]
impl DaemonInterface for XpcDaemonInterface {
async fn print_version(&mut self) -> Result<()> {
// Open an XPC connection to the daemon service
let mut conn = XpcConnection::new(SERVICE_NAME);
let mut incoming = conn.connect();
// Send a GetVersion request as a dictionary message
let mut dict = HashMap::new();
dict.insert(
GET_VERSION_METHOD.to_string(),
Message::String(String::new()),
);
conn.send_message(Message::Dictionary(dict));
// Wait for a single string reply (futures-preview StreamFuture returns (Option<Item>, Stream))
let (opt_msg, _) = match block_on(incoming.next()) {
Ok(pair) => pair,
Err(e) => {
eprintln!("Error reading XPC reply: {:?}", e);
return Ok(());
}
};
if let Some(Message::String(ver_raw)) = opt_msg {
// Trim the trailing NUL if present
let version = ver_raw.trim_end_matches('\0');
println!("Server version: {}", version);
} else {
eprintln!("Unexpected XPC reply for GetVersion");
}
Ok(())
}
// Remaining methods unimplemented on macOS
async fn print_conversations(&mut self) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn sync_conversations(&mut self, _conversation_id: Option<String>) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn sync_conversations_list(&mut self) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn print_messages(
&mut self,
_conversation_id: String,
_last_message_id: Option<String>,
) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn enqueue_outgoing_message(
&mut self,
_conversation_id: String,
_text: String,
) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn wait_for_signals(&mut self) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn config(&mut self, _cmd: ConfigCommands) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn delete_all_conversations(&mut self) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn download_attachment(&mut self, _attachment_id: String) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn upload_attachment(&mut self, _path: String) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
async fn mark_conversation_as_read(&mut self, _conversation_id: String) -> Result<()> {
Err(anyhow::anyhow!("Feature not implemented for XPC"))
}
}