use clap::Parser;
use crate::{commands::tx, 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 selling: builder::Asset,
#[arg(long)]
pub buying: builder::Asset,
#[arg(long)]
pub amount: builder::Amount,
#[arg(long)]
pub price: String,
#[arg(long, default_value = "0")]
pub offer_id: i64,
}
impl TryFrom<&Cmd> for xdr::OperationBody {
type Error = tx::args::Error;
fn try_from(
Cmd {
tx,
op:
Args {
selling,
buying,
amount,
price,
offer_id,
},
}: &Cmd,
) -> Result<Self, Self::Error> {
let price_parts: Vec<&str> = price.split(':').collect();
if price_parts.len() != 2 {
return Err(tx::args::Error::InvalidPrice(price.clone()));
}
let n: i32 = price_parts[0]
.parse()
.map_err(|_| tx::args::Error::InvalidPrice(price.clone()))?;
let d: i32 = price_parts[1]
.parse()
.map_err(|_| tx::args::Error::InvalidPrice(price.clone()))?;
if d == 0 {
return Err(tx::args::Error::InvalidPrice(
"denominator cannot be zero".to_string(),
));
}
Ok(xdr::OperationBody::ManageSellOffer(
xdr::ManageSellOfferOp {
selling: tx.resolve_asset(selling)?,
buying: tx.resolve_asset(buying)?,
amount: amount.into(),
price: xdr::Price { n, d },
offer_id: *offer_id,
},
))
}
}