Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add macro for code metadata #914

Merged
merged 18 commits into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions Cargo.lock

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

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ git = "https://github.com/stellar/rs-stellar-xdr"
rev = "bcf6f4c3a9dd32822a20af89880650a421d10e7f"
default-features = false

# [patch."https://github.com/stellar/rs-soroban-env"]
# soroban-env-common = { path = "../rs-soroban-env/soroban-env-common" }
# soroban-env-guest = { path = "../rs-soroban-env/soroban-env-guest" }
# soroban-env-host = { path = "../rs-soroban-env/soroban-env-host/" }
# [patch."https://github.com/stellar/rs-stellar-xdr"]
# stellar-xdr = { path = "../rs-stellar-xdr/" }
[patch."https://github.com/stellar/rs-soroban-env"]
soroban-env-common = { path = "../rs-soroban-env/soroban-env-common" }
soroban-env-guest = { path = "../rs-soroban-env/soroban-env-guest" }
soroban-env-host = { path = "../rs-soroban-env/soroban-env-host/" }
[patch."https://github.com/stellar/rs-stellar-xdr"]
stellar-xdr = { path = "../rs-stellar-xdr/" }

[profile.dev]
overflow-checks = true
Expand Down
72 changes: 71 additions & 1 deletion soroban-sdk-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use derive_struct_tuple::derive_type_struct_tuple;
use darling::FromMeta;
use proc_macro::TokenStream;
use proc_macro2::{Literal, Span, TokenStream as TokenStream2};
use quote::quote;
use quote::{format_ident, quote};
use sha2::{Digest, Sha256};
use std::fs;
use syn::{
Expand All @@ -35,6 +35,8 @@ use self::derive_client::ClientItem;

use soroban_spec::gen::rust::{generate_from_wasm, GenerateFromFileError};

use stellar_xdr::{ScMetaEntry, ScMetaV0, StringM, WriteXdr};

fn default_crate_path() -> Path {
parse_str("soroban_sdk").unwrap()
}
Expand Down Expand Up @@ -95,6 +97,74 @@ pub fn contractimpl(_metadata: TokenStream, input: TokenStream) -> TokenStream {
}
}

#[derive(Debug, FromMeta)]
struct MetadataArgs {
key: String,
val: String,
}

#[proc_macro]
pub fn contractmeta(metadata: TokenStream) -> TokenStream {
let args = parse_macro_input!(metadata as AttributeArgs);
let args = match MetadataArgs::from_list(&args) {
Ok(v) => v,
Err(e) => return e.write_errors().into(),
};

let gen = {
let key: StringM<10> = match args.key.clone().try_into() {
Ok(k) => k,
Err(e) => {
return Error::new(Span::call_site(), e.to_string())
.into_compile_error()
.into()
}
};

let val: StringM<256> = match args.val.try_into() {
Ok(k) => k,
Err(e) => {
return Error::new(Span::call_site(), e.to_string())
.into_compile_error()
.into()
}
};

let meta_v0 = ScMetaV0 { key, val };
let meta_entry = ScMetaEntry::ScMetaV0(meta_v0);
let metadata_xdr: Vec<u8> = match meta_entry.to_xdr() {
Ok(v) => v,
Err(e) => {
return Error::new(Span::call_site(), e.to_string())
.into_compile_error()
.into()
}
};

let metadata_xdr_lit = proc_macro2::Literal::byte_string(metadata_xdr.as_slice());
let metadata_xdr_len = metadata_xdr.len();

let ident = format_ident!(
"__CONTRACT_KEY_{}",
args.key
.as_bytes()
.iter()
.map(|b| format!("{b:02x}"))
.collect::<String>()
);
quote! {
#[doc(hidden)]
#[cfg_attr(target_family = "wasm", link_section = "contractmetav0")]
static #ident: [u8; #metadata_xdr_len] = *#metadata_xdr_lit;
}
};

quote! {
#gen
}
.into()
}

#[derive(Debug, FromMeta)]
struct ContractTypeArgs {
#[darling(default = "default_crate_path")]
Expand Down
1 change: 1 addition & 0 deletions soroban-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ pub use soroban_sdk_macros::contractimport;
/// # fn main() { }
/// ```
pub use soroban_sdk_macros::contractimpl;
pub use soroban_sdk_macros::contractmeta;

/// Generates conversions from the struct/enum from/into a `RawVal`.
///
Expand Down