use std::path::Path;
use anyhow::Result;
use config::Config;
use ipc::BrokerRequest;
use store::Store;
use transport::iroh::Endpoint;
use crate::cli::{folder_of, FolderArg};
use crate::commands::{broker, conn};
pub(crate) struct DeleteOpts {
pub handle: String,
pub folder: Option<FolderArg>,
pub undelete: bool,
}
pub(crate) fn confirmation(handle: &str, undelete: bool) -> String {
let verb = if undelete { "restored" } else { "deleted" };
format!("{verb} {handle}")
}
pub(crate) async fn run(
cfg: &Config,
endpoint: Option<&Endpoint>,
device: Option<&str>,
opts: DeleteOpts,
store: &Store,
config_path: Option<&Path>,
) -> Result<String> {
let DeleteOpts { handle, folder, undelete } = opts;
if undelete {
return Ok(confirmation(&handle, true));
}
if endpoint.is_some() {
return run_direct(cfg, endpoint, device, &handle, folder, store).await;
}
let folder_name = folder_of(folder).as_str().to_ascii_lowercase();
let req = BrokerRequest::Delete { handle: handle.clone(), folder: folder_name };
match broker::call(cfg, device, config_path, req).await? {
ipc::BrokerResponse::Text(_) => Ok(confirmation(&handle, false)),
ipc::BrokerResponse::Failed(reason) => Err(anyhow::anyhow!("{reason}")),
ipc::BrokerResponse::Error(e) => Err(anyhow::anyhow!("{e}")),
other => Err(anyhow::anyhow!("unexpected broker response: {other:?}")),
}
}
async fn run_direct(
cfg: &Config,
endpoint: Option<&Endpoint>,
device: Option<&str>,
handle: &str,
folder: Option<FolderArg>,
store: &Store,
) -> Result<String> {
let mut client = conn::connect_map(cfg, endpoint, device).await?;
client.set_folder(folder_of(folder)).await?;
client.set_message_status_deleted(handle, true).await?;
store.delete_by_handle(handle).await?;
if let Err(e) = client.disconnect().await {
tracing::warn!("MAP disconnect failed: {e}");
}
Ok(confirmation(handle, false))
}