101 lines
3.6 KiB
Rust
101 lines
3.6 KiB
Rust
|
|
#![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"))
|
||
|
|
}
|
||
|
|
}
|