use std::collections::HashMap;
use std::path::{Path, PathBuf};
use anyhow::Result;
use serde_json::json;
use super::wire::{AheadBehindEntryWire, SafetyReportWire};
use crate::cli::daemon::call_service;
use crate::daemon::client::DaemonClient;
const SERVICE: &str = "worktrees";
#[derive(Debug, Clone)]
pub struct WorktreesClient {
inner: DaemonClient,
}
impl WorktreesClient {
pub fn new(socket: impl Into<PathBuf>) -> Self {
Self {
inner: DaemonClient::new(socket),
}
}
fn socket(&self) -> &Path {
self.inner.socket_path()
}
pub async fn fetch_ahead_behind(
&self,
paths: &[PathBuf],
) -> Result<HashMap<PathBuf, AheadBehindEntryWire>> {
if paths.is_empty() {
return Ok(HashMap::new());
}
let payload = json!({ "paths": paths });
let value = call_service(self.socket(), SERVICE, "ahead-behind", payload).await?;
let raw: HashMap<String, AheadBehindEntryWire> = value
.get("results")
.cloned()
.map(serde_json::from_value)
.transpose()?
.unwrap_or_default();
Ok(raw
.into_iter()
.map(|(k, v)| (PathBuf::from(k), v))
.collect())
}
pub async fn open(&self, path: &Path) -> Result<()> {
call_service(self.socket(), SERVICE, "open", json!({ "path": path })).await?;
Ok(())
}
pub async fn close_check(&self, path: &Path) -> Result<SafetyReportWire> {
let value = call_service(
self.socket(),
SERVICE,
"close",
json!({ "path": path, "remove": true }),
)
.await?;
Ok(serde_json::from_value(value)?)
}
pub async fn close_execute(&self, path: &Path, remove: bool) -> Result<()> {
let payload = if remove {
json!({ "path": path, "remove": true, "confirmed": true })
} else {
json!({ "path": path, "remove": false })
};
call_service(self.socket(), SERVICE, "close", payload).await?;
Ok(())
}
}