use crate::{Result, TauriMcpError};
use serde_json::Value;
use std::collections::HashMap;
use tracing::{debug, info};
pub struct IpcManager {
known_handlers: HashMap<String, Vec<String>>,
}
impl IpcManager {
pub fn new() -> Self {
Self {
known_handlers: HashMap::new(),
}
}
pub async fn list_ipc_handlers(&self, process_id: &str) -> Result<Vec<String>> {
info!("Listing IPC handlers for process: {}", process_id);
if let Some(handlers) = self.known_handlers.get(process_id) {
Ok(handlers.clone())
} else {
let default_handlers = vec![
"tauri".to_string(),
"app_ready".to_string(),
"window_created".to_string(),
"window_destroyed".to_string(),
"webview_created".to_string(),
"webview_destroyed".to_string(),
"event".to_string(),
"invoke".to_string(),
];
Ok(default_handlers)
}
}
pub async fn call_ipc_command(&self, process_id: &str, command_name: &str, args: Value) -> Result<Value> {
info!("Calling IPC command '{}' for process {} with args: {}",
command_name, process_id, args);
match command_name {
"tauri" => {
Ok(serde_json::json!({
"status": "success",
"message": "Tauri command executed",
"version": "2.0.0"
}))
},
"app_ready" => {
Ok(serde_json::json!({
"status": "success",
"ready": true,
"timestamp": chrono::Utc::now().to_rfc3339()
}))
},
"window_created" => {
Ok(serde_json::json!({
"status": "success",
"window_id": uuid::Uuid::new_v4().to_string(),
"title": args.get("title").and_then(|v| v.as_str()).unwrap_or("Tauri Window")
}))
},
"invoke" => {
if let Some(cmd) = args.get("cmd").and_then(|v| v.as_str()) {
Ok(serde_json::json!({
"status": "success",
"command": cmd,
"result": "Command invoked successfully"
}))
} else {
Err(TauriMcpError::IpcError("Missing 'cmd' parameter for invoke".to_string()))
}
},
_ => {
Ok(serde_json::json!({
"status": "success",
"command": command_name,
"message": format!("Custom command '{}' executed", command_name),
"args": args
}))
}
}
}
pub async fn register_handler(&mut self, process_id: &str, handler_name: &str) -> Result<()> {
info!("Registering IPC handler '{}' for process: {}", handler_name, process_id);
let handlers = self.known_handlers.entry(process_id.to_string()).or_insert_with(Vec::new);
if !handlers.contains(&handler_name.to_string()) {
handlers.push(handler_name.to_string());
}
Ok(())
}
pub async fn unregister_handler(&mut self, process_id: &str, handler_name: &str) -> Result<()> {
info!("Unregistering IPC handler '{}' for process: {}", handler_name, process_id);
if let Some(handlers) = self.known_handlers.get_mut(process_id) {
handlers.retain(|h| h != handler_name);
}
Ok(())
}
pub async fn emit_event(&self, process_id: &str, event_name: &str, payload: Value) -> Result<()> {
info!("Emitting event '{}' for process {} with payload: {}",
event_name, process_id, payload);
Ok(())
}
pub async fn listen_to_event(&self, process_id: &str, event_name: &str) -> Result<()> {
info!("Listening to event '{}' for process: {}", event_name, process_id);
Ok(())
}
pub async fn unlisten_event(&self, process_id: &str, event_name: &str) -> Result<()> {
info!("Unlistening from event '{}' for process: {}", event_name, process_id);
Ok(())
}
pub async fn get_app_state(&self, process_id: &str, key: &str) -> Result<Value> {
info!("Getting app state for key '{}' in process: {}", key, process_id);
Ok(serde_json::json!({
"key": key,
"value": null,
"exists": false
}))
}
pub async fn set_app_state(&self, process_id: &str, key: &str, value: Value) -> Result<()> {
info!("Setting app state for key '{}' in process {} to: {}",
key, process_id, value);
Ok(())
}
}