Skip to content

Commit

Permalink
PR comment
Browse files Browse the repository at this point in the history
  • Loading branch information
Ifropc committed Aug 8, 2024
1 parent 21c54af commit 4770347
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 224 deletions.
46 changes: 36 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ version = "21.2.0"
version = "=21.2.0"

[workspace.dependencies.soroban-spec-rust]
version = "=21.2.0"
# TODO
version = "=21.4.0"
git = "https://github.com/stellar/rs-soroban-sdk"
rev = "70a4989b21d84b14216cbf00c06b8f7d074864fa"

[workspace.dependencies.soroban-spec-json]
version = "=21.2.0"
Expand Down
212 changes: 0 additions & 212 deletions cmd/crates/soroban-spec-tools/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use soroban_env_host::xdr::{
ScSpecFunctionV0, ScSpecUdtEnumV0, ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionV0,
StringM, WriteXdr,
};
use stellar_xdr::curr::{ScSpecTypeDef, ScSpecUdtUnionCaseV0, VecM};

pub struct Spec {
pub env_meta_base64: Option<String>,
Expand Down Expand Up @@ -285,214 +284,3 @@ fn format_name(lib: &StringM<80>, name: &StringM<60>) -> String {
name.to_utf8_string_lossy()
}
}

pub fn pretty_spec(spec: &Vec<ScSpecEntry>) -> String {
let mut res = vec![
"/////// Generated pseudocode contract spec from an XDR: \\\\\\\\\\\\\\\n".to_string(),
];

let mut functions = Vec::new();

for spec_entry in spec {
match spec_entry {
ScSpecEntry::FunctionV0(func) => functions.push(func),
ScSpecEntry::UdtUnionV0(udt) => res.push(pretty_union(udt)),
ScSpecEntry::UdtStructV0(udt) => res.push(pretty_struct(udt)),
ScSpecEntry::UdtEnumV0(udt) => res.push(pretty_enum(udt)),
ScSpecEntry::UdtErrorEnumV0(udt) => res.push(pretty_error(udt)),
};
}

if !functions.is_empty() {
res.push(format!(
"pub trait ContractTrait {{\n{}}}",
functions.iter().map(|f| pretty_func(f)).join("")
));
}

res.iter().join("\n")
}

const IDENT: &str = " ";

fn pretty_func(func: &ScSpecFunctionV0) -> String {
let mut res = pretty_doc(&func.doc, IDENT);

res.push_str(&format!("{}pub fn {}(", IDENT, func.name.0));

// TODO: handle input.doc;
res.push_str(
&func
.inputs
.as_vec()
.iter()
.map(|x| format!("{}: {}", x.name, pretty_type(&x.type_)))
.join(", "),
);

let outputs = func.outputs.as_vec();

res.push(')');

match outputs.len() {
0 => {}
1 => res.push_str(&format!(" -> {}", pretty_type(&outputs[0]))),
_ => unreachable!("Outputs is VecM<1>"),
};

res.push_str(";\n");
res
}

fn pretty_union(udt_union: &ScSpecUdtUnionV0) -> String {
// TODO: handle lib
let mut res = pretty_doc(&udt_union.doc, "");

let body = udt_union
.cases
.as_vec()
.iter()
.map(|u| match u {
ScSpecUdtUnionCaseV0::VoidV0(void) => {
format!("{}{}{}", pretty_doc(&void.doc, IDENT), IDENT, void.name)
}
ScSpecUdtUnionCaseV0::TupleV0(tuple) => format!(
"{}{}{}{}",
pretty_doc(&tuple.doc, IDENT),
IDENT,
tuple.name,
pretty_tuple(&tuple.type_)
),
})
.join(",\n");
res.push_str(&format!("pub enum {} {{\n{}\n}}", udt_union.name, body));

res
}

fn pretty_struct(udt_struct: &ScSpecUdtStructV0) -> String {
// TODO: handle lib
let mut res = pretty_doc(&udt_struct.doc, "");

let body = udt_struct
.fields
.as_vec()
.iter()
.map(|f| {
format!(
"{}{}pub {}: {}",
pretty_doc(&f.doc, IDENT),
IDENT,
f.name,
pretty_type(&f.type_)
)
})
.join(",\n");

res.push_str(&format!("pub struct {} {{\n{}\n}}", udt_struct.name, body));

res
}

fn pretty_enum(udt: &ScSpecUdtEnumV0) -> String {
// TODO: handle lib
let mut res = pretty_doc(&udt.doc, "");

let body = udt
.cases
.as_vec()
.iter()
.map(|case| {
format!(
"{}{}{} = {}",
pretty_doc(&case.doc, IDENT),
IDENT,
case.name,
case.value
)
})
.join(",\n");

res.push_str(&format!("pub enum {} {{\n{}\n}}", udt.name, body));

res
}

fn pretty_error(udt: &ScSpecUdtErrorEnumV0) -> String {
// TODO: handle lib
let mut res = pretty_doc(&udt.doc, "");

let body = udt
.cases
.as_vec()
.iter()
.map(|case| {
format!(
"{}{}{} = {}",
pretty_doc(&case.doc, IDENT),
IDENT,
case.name,
case.value
)
})
.join(",\n");

res.push_str(&format!("pub enum {} {{\n{}\n}}", udt.name, body));

res
}

fn pretty_type(def: &ScSpecTypeDef) -> String {
match def {
ScSpecTypeDef::U32
| ScSpecTypeDef::I32
| ScSpecTypeDef::U64
| ScSpecTypeDef::I64
| ScSpecTypeDef::U128
| ScSpecTypeDef::I128
| ScSpecTypeDef::U256
| ScSpecTypeDef::I256 => def.name().to_string().to_lowercase(),

ScSpecTypeDef::Val
| ScSpecTypeDef::Bool
| ScSpecTypeDef::Void
| ScSpecTypeDef::Error
| ScSpecTypeDef::Timepoint
| ScSpecTypeDef::Duration
| ScSpecTypeDef::Bytes
| ScSpecTypeDef::String
| ScSpecTypeDef::Symbol
| ScSpecTypeDef::Address => def.name().to_string(),

ScSpecTypeDef::Option(x) => format!("Option<{}>", pretty_type(&x.value_type)),
ScSpecTypeDef::Result(r) => format!(
"Result<{}, {}>",
pretty_type(&r.ok_type),
pretty_type(&r.error_type)
),
ScSpecTypeDef::Vec(v) => format!("Vec<{}>", pretty_type(&v.element_type)),
ScSpecTypeDef::Map(m) => format!(
"Map<{}, {}>",
pretty_type(&m.key_type),
pretty_type(&m.value_type)
),
ScSpecTypeDef::Tuple(vec) => pretty_tuple(&vec.value_types),
ScSpecTypeDef::BytesN(spec) => format!("BytesN<{}>", spec.n),
ScSpecTypeDef::Udt(u) => format!("{}", u.name),
}
}

fn pretty_doc(doc: &StringM<1024>, ident: &str) -> String {
if doc.len() != 0 {
return format!(
"{}/// {}\n",
ident,
doc.to_string().replace("\\n", &format!("\n{ident}/// "))
);
}
String::new()
}

fn pretty_tuple(vec: &VecM<ScSpecTypeDef, 12>) -> String {
format!("({})", vec.iter().map(pretty_type).join(", "))
}
5 changes: 4 additions & 1 deletion cmd/soroban-cli/src/commands/contract/info/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::commands::contract::info::interface::Error::NoInterfacePresent;
use crate::commands::contract::info::shared;
use crate::commands::contract::info::shared::fetch_wasm;
use clap::{command, Parser};
use soroban_spec_rust::ToFormattedString;
use soroban_spec_tools::contract;
use soroban_spec_tools::contract::Spec;

Expand Down Expand Up @@ -47,7 +48,9 @@ impl Cmd {
InfoOutput::XdrBase64 => base64,
InfoOutput::Json => serde_json::to_string(&spec)?,
InfoOutput::JsonFormatted => serde_json::to_string_pretty(&spec)?,
InfoOutput::Pretty => contract::pretty_spec(&spec),
InfoOutput::Pretty => soroban_spec_rust::generate_without_file(&spec)
.to_formatted_string()
.expect("Unexpected spec format error"),
};

Ok(res)
Expand Down

0 comments on commit 4770347

Please sign in to comment.