use clap::Parser;
use crate::{commands::tx, config::address, tx::builder, xdr};
#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[command(flatten)]
pub tx: tx::Args,
#[clap(flatten)]
pub op: Args,
}
#[derive(Debug, clap::Args, Clone)]
pub struct Args {
#[arg(long)]
pub send_asset: builder::Asset,
#[arg(long)]
pub send_max: builder::Amount,
#[arg(long)]
pub destination: address::UnresolvedMuxedAccount,
#[arg(long)]
pub dest_asset: builder::Asset,
#[arg(long)]
pub dest_amount: builder::Amount,
#[arg(long, value_delimiter = ',')]
pub path: Vec<builder::Asset>,
}
impl TryFrom<&Cmd> for xdr::OperationBody {
type Error = tx::args::Error;
fn try_from(
Cmd {
tx,
op:
Args {
send_asset,
send_max,
destination,
dest_asset,
dest_amount,
path,
},
}: &Cmd,
) -> Result<Self, Self::Error> {
if path.len() > 5 {
return Err(tx::args::Error::InvalidPath(
"Path cannot contain more than 5 assets".to_string(),
));
}
let path_assets: Result<Vec<xdr::Asset>, _> =
path.iter().map(|asset| tx.resolve_asset(asset)).collect();
let path_assets = path_assets?;
let path_vec = path_assets.try_into().map_err(|_| {
tx::args::Error::InvalidPath("Failed to convert path to VecM".to_string())
})?;
Ok(xdr::OperationBody::PathPaymentStrictReceive(
xdr::PathPaymentStrictReceiveOp {
send_asset: tx.resolve_asset(send_asset)?,
send_max: send_max.into(),
destination: tx.resolve_muxed_address(destination)?,
dest_asset: tx.resolve_asset(dest_asset)?,
dest_amount: dest_amount.into(),
path: path_vec,
},
))
}
}