use super::*;
use clap::Parser;
#[derive(Parser, Debug)]
#[command(group(
// Ensure exactly one source is specified.
clap::ArgGroup::new("source").required(true).multiple(false)
))]
#[command(group(
// Ensure at most one mode is specified and ony if using "id" as a source.
// The `conflicts_with_all` here should not be required but it looks like Clap is getting a little confused
clap::ArgGroup::new("mode")
.required(false)
.multiple(false)
.requires("ID").conflicts_with_all(["from_io", "from_transition", "from_program"]
)
))]
pub struct LeoTransaction {
#[clap(name = "ID", help = "The ID of the transaction to fetch", group = "source")]
pub(crate) id: Option<String>,
#[arg(short, long, help = "Return more information about a confirmed transaction", group = "mode")]
pub(crate) confirmed: bool,
#[arg(short, long, help = "Get the original (unconfirmed) transaction", group = "mode")]
pub(crate) unconfirmed: bool,
#[arg(
value_name = "INPUT_OR_OUTPUT_ID",
long,
help = "Get the ID of the transaction that an input or output ID occurred in",
group = "source"
)]
pub(crate) from_io: Option<String>,
#[arg(
value_name = "TRANSITION_ID",
long,
help = "Get the ID of the transaction containing the specified transition",
group = "source"
)]
pub(crate) from_transition: Option<String>,
#[arg(
value_name = "PROGRAM",
long,
help = "Get the ID of the transaction that the specified program was deployed in",
group = "source"
)]
pub(crate) from_program: Option<String>,
}
impl Command for LeoTransaction {
type Input = ();
type Output = String;
fn log_span(&self) -> Span {
tracing::span!(tracing::Level::INFO, "Leo")
}
fn prelude(&self, _context: Context) -> Result<Self::Input> {
Ok(())
}
fn apply(self, _context: Context, _: Self::Input) -> Result<Self::Output> {
let url = if let Some(io_id) = self.from_io {
let field = is_valid_field(&io_id)?;
format!("find/transitionID/{field}")
} else if let Some(transition) = self.from_transition {
is_valid_transition_id(&transition)?;
format!("find/transactionID/{transition}")
} else if let Some(program) = self.from_program {
if !leo_package::is_valid_program_name(&program) {
return Err(crate::errors::invalid_package_name("program", program).into());
}
format!("find/transactionID/deployment/{program}")
} else if let Some(id) = self.id {
is_valid_transaction_id(&id)?;
if self.confirmed {
format!("transaction/confirmed/{id}")
} else if self.unconfirmed {
format!("transaction/unconfirmed/{id}")
} else {
format!("transaction/{id}")
}
} else {
unreachable!("All command paths covered.")
};
Ok(url)
}
}