use anyhow::{Context, Result};
use clap::Parser;
use wasmcloud_control_interface::{CtlResponse, InterfaceLinkDefinition};
use crate::{cli::CliConnectionOpts, common::boxed_err_to_anyhow, config::WashConnectionOptions};
use super::validate_component_id;
#[derive(Parser, Debug, Clone)]
pub struct LinkDelCommand {
#[clap(flatten)]
pub opts: CliConnectionOpts,
#[clap(name = "source-id", value_parser = validate_component_id)]
pub source_id: String,
#[clap(short = 'l', long = "link-name")]
pub link_name: Option<String>,
#[clap(name = "wit-namespace")]
pub wit_namespace: String,
#[clap(name = "wit-package")]
pub wit_package: String,
}
#[derive(Parser, Debug, Clone)]
pub struct LinkPutCommand {
#[clap(flatten)]
pub opts: CliConnectionOpts,
#[clap(name = "source-id", value_parser = validate_component_id)]
pub source_id: String,
#[clap(name = "target", value_parser = validate_component_id)]
pub target: String,
#[clap(name = "wit-namespace")]
pub wit_namespace: String,
#[clap(name = "wit-package")]
pub wit_package: String,
#[clap(long = "interface", alias = "interfaces", required = true)]
pub interfaces: Vec<String>,
#[clap(long = "source-config")]
pub source_config: Vec<String>,
#[clap(long = "target-config")]
pub target_config: Vec<String>,
#[clap(short = 'l', long = "link-name")]
pub link_name: Option<String>,
}
#[derive(Parser, Debug, Clone)]
pub struct LinkQueryCommand {
#[clap(flatten)]
pub opts: CliConnectionOpts,
}
#[derive(Debug, Clone, Parser)]
pub enum LinkCommand {
#[clap(name = "query", alias = "get")]
Query(LinkQueryCommand),
#[clap(name = "put")]
Put(LinkPutCommand),
#[clap(name = "del", alias = "delete")]
Del(LinkDelCommand),
}
pub async fn get_links(wco: WashConnectionOptions) -> Result<Vec<InterfaceLinkDefinition>> {
wco.into_ctl_client(None)
.await?
.get_links()
.await
.map(|ctl| ctl.response.unwrap_or_default())
.map_err(boxed_err_to_anyhow)
}
pub async fn delete_link(
wco: WashConnectionOptions,
source_id: &str,
link_name: &str,
wit_namespace: &str,
wit_package: &str,
) -> Result<CtlResponse<()>> {
let ctl_client = wco.into_ctl_client(None).await?;
ctl_client
.delete_link(source_id, link_name, wit_namespace, wit_package)
.await
.map_err(boxed_err_to_anyhow)
.with_context(|| {
format!(
"Failed to remove link from {source_id} on {wit_namespace}:{wit_package} with link name {link_name}",
)
})
}
pub async fn put_link(
wco: WashConnectionOptions,
link: InterfaceLinkDefinition,
) -> Result<CtlResponse<()>> {
let ctl_client = wco.into_ctl_client(None).await?;
ctl_client
.put_link(link.clone())
.await
.map_err(boxed_err_to_anyhow)
.with_context(|| {
format!(
"Failed to create link between {} and {} on {}:{}/{:?}. Link name: {}",
link.source_id,
link.target,
link.wit_namespace,
link.wit_package,
link.interfaces,
link.name
)
})
}