soroban_cli/commands/contract/info/
meta.rs1use std::fmt::Debug;
2use std::fmt::Write;
3
4use crate::commands::contract::info::meta::Error::{NoMetaPresent, NoSACMeta};
5use crate::commands::contract::info::shared::{self, fetch, Fetched, MetasInfoOutput};
6use crate::commands::global;
7use crate::print::Print;
8use clap::{command, Parser};
9use soroban_spec_tools::contract;
10use soroban_spec_tools::contract::Spec;
11use stellar_xdr::curr::{ScMetaEntry, ScMetaV0};
12
13#[derive(Parser, Debug, Clone)]
14pub struct Cmd {
15 #[command(flatten)]
16 pub common: shared::Args,
17 #[arg(long, default_value = "text")]
19 pub output: MetasInfoOutput,
20}
21
22#[derive(thiserror::Error, Debug)]
23pub enum Error {
24 #[error(transparent)]
25 Wasm(#[from] shared::Error),
26 #[error(transparent)]
27 Spec(#[from] contract::Error),
28 #[error("Stellar asset contract doesn't contain meta information")]
29 NoSACMeta(),
30 #[error("no meta present in provided WASM file")]
31 NoMetaPresent(),
32 #[error(transparent)]
33 Json(#[from] serde_json::Error),
34}
35
36impl Cmd {
37 pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
38 let print = Print::new(global_args.quiet);
39 let Fetched { contract, .. } = fetch(&self.common, &print).await?;
40
41 let spec = match contract {
42 shared::Contract::Wasm { wasm_bytes } => Spec::new(&wasm_bytes)?,
43 shared::Contract::StellarAssetContract => return Err(NoSACMeta()),
44 };
45
46 let Some(meta_base64) = spec.meta_base64 else {
47 return Err(NoMetaPresent());
48 };
49
50 let res = match self.output {
51 MetasInfoOutput::XdrBase64 => meta_base64,
52 MetasInfoOutput::Json => serde_json::to_string(&spec.meta)?,
53 MetasInfoOutput::JsonFormatted => serde_json::to_string_pretty(&spec.meta)?,
54 MetasInfoOutput::Text => {
55 let mut meta_str = "Contract meta:\n".to_string();
56
57 for meta_entry in &spec.meta {
58 match meta_entry {
59 ScMetaEntry::ScMetaV0(ScMetaV0 { key, val }) => {
60 let key = key.to_string();
61 let val = match key.as_str() {
62 "rsver" => format!("{val} (Rust version)"),
63 "rssdkver" => {
64 format!("{val} (Soroban SDK version and its commit hash)")
65 }
66 _ => val.to_string(),
67 };
68 let _ = writeln!(meta_str, " • {key}: {val}");
69 }
70 }
71 }
72
73 meta_str
74 }
75 };
76
77 println!("{res}");
78
79 Ok(())
80 }
81}