Skip to content

Commit

Permalink
Merge branch 'feat/custom-derives' into updatedeps
Browse files Browse the repository at this point in the history
  • Loading branch information
glihm committed Jul 26, 2024
2 parents a42e1dc + d16d4bf commit 2433cc3
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 21 deletions.
14 changes: 9 additions & 5 deletions contracts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ generate_artifacts:
jq .abi ${scarb_build}simple_interface${sierra} > ${artifacts}simple_interface.abi.json
jq .abi ${scarb_build}structs${sierra} > ${artifacts}structs.abi.json
jq .abi ${scarb_build}byte_array${sierra} > ${artifacts}byte_array.abi.json
jq .abi ${scarb_build}gen${sierra} > ${artifacts}gen.abi.json

generate_rust:
scarb build
Expand Down Expand Up @@ -50,11 +51,14 @@ setup_byte_array:
# starkli declare target/dev/contracts_basic.sierra.json ${config}
# starkli deploy ${class_hash} --salt 0x1234 ${config}

# # Declare and deploy the basic contract on katana.
# setup_gen:
# $(eval class_hash=$(shell starkli class-hash target/dev/contracts_gen.sierra.json))
# starkli declare target/dev/contracts_gen.sierra.json ${config}
# starkli deploy ${class_hash} --salt 0x1234 ${config}
# Declare and deploy the basic contract on katana.
setup_gen:
@set -x; \
scarb build; \
class_hash=$$(starkli class-hash ${scarb_build}gen${sierra}); \
starkli declare ${scarb_build}gen${sierra} ${config}; \
sleep 2; \
starkli deploy "$${class_hash}" --salt 0x1234 ${config}

# # Declare and deploy the event contract on katana.
# setup_event:
Expand Down
1 change: 1 addition & 0 deletions contracts/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mod abicov {

mod simple_get_set;
mod basic;
mod gen;
2 changes: 2 additions & 0 deletions crates/rs-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fn abigen_internal(input: TokenStream) -> TokenStream {
&contract_name.to_string(),
&abi_tokens,
contract_abi.execution_version,
&contract_abi.derives,
);

if let Some(out_path) = contract_abi.output_path {
Expand Down Expand Up @@ -61,6 +62,7 @@ fn abigen_internal_legacy(input: TokenStream) -> TokenStream {
&contract_name.to_string(),
&abi_tokens,
cainome_rs::ExecutionVersion::V1,
&[],
);

if let Some(out_path) = contract_abi.output_path {
Expand Down
12 changes: 12 additions & 0 deletions crates/rs-macro/src/macro_inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub(crate) struct ContractAbi {
pub output_path: Option<String>,
pub type_aliases: HashMap<String, String>,
pub execution_version: ExecutionVersion,
pub derives: Vec<String>,
}

impl Parse for ContractAbi {
Expand Down Expand Up @@ -89,6 +90,7 @@ impl Parse for ContractAbi {
let mut output_path: Option<String> = None;
let mut execution_version = ExecutionVersion::V1;
let mut type_aliases = HashMap::new();
let mut derives = Vec::new();

loop {
if input.parse::<Token![,]>().is_err() {
Expand Down Expand Up @@ -135,6 +137,15 @@ impl Parse for ContractAbi {
syn::Error::new(content.span(), format!("Invalid execution version: {}", e))
})?;
}
"derives" => {
let content;
parenthesized!(content in input);
let parsed = content.parse_terminated(Spanned::<Type>::parse, Token![,])?;

for derive in parsed {
derives.push(derive.to_token_stream().to_string());
}
}
_ => panic!("unexpected named parameter `{}`", name),
}
}
Expand All @@ -145,6 +156,7 @@ impl Parse for ContractAbi {
output_path,
type_aliases,
execution_version,
derives,
})
}
}
Expand Down
15 changes: 9 additions & 6 deletions crates/rs/src/expand/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::expand::utils;
pub struct CairoEnum;

impl CairoEnum {
pub fn expand_decl(composite: &Composite) -> TokenStream2 {
pub fn expand_decl(composite: &Composite, derives: &[String]) -> TokenStream2 {
if composite.is_builtin() {
return quote!();
}
Expand All @@ -29,6 +29,12 @@ impl CairoEnum {
}
}

let mut internal_derives = vec![];

for d in derives {
internal_derives.push(utils::str_to_type(d));
}

if composite.is_generic() {
let gen_args: Vec<Ident> = composite
.generic_args
Expand All @@ -42,18 +48,15 @@ impl CairoEnum {
// Add one phantom for each generic type.
// Those phantom fields are ignored by serde.

// TODO: as for struct, we need to have a better way for the user to specify the
// traits to derive.

quote! {
#[derive(Debug, PartialEq, PartialOrd, Clone, serde::Serialize, serde::Deserialize)]
#[derive(#(#internal_derives,)*)]
pub enum #enum_name<#(#gen_args),*> {
#(#variants),*
}
}
} else {
quote! {
#[derive(Debug, PartialEq, PartialOrd, Clone, serde::Serialize, serde::Deserialize)]
#[derive(#(#internal_derives,)*)]
pub enum #enum_name {
#(#variants),*
}
Expand Down
15 changes: 9 additions & 6 deletions crates/rs/src/expand/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::expand::utils;
pub struct CairoStruct;

impl CairoStruct {
pub fn expand_decl(composite: &Composite) -> TokenStream2 {
pub fn expand_decl(composite: &Composite, derives: &[String]) -> TokenStream2 {
if composite.is_builtin() {
return quote!();
}
Expand All @@ -35,6 +35,12 @@ impl CairoStruct {
}
}

let mut internal_derives = vec![];

for d in derives {
internal_derives.push(utils::str_to_type(d));
}

if composite.is_generic() {
let gen_args: Vec<Ident> = composite
.generic_args
Expand All @@ -48,18 +54,15 @@ impl CairoStruct {
// Add one phantom for each generic type.
// Those phantom fields are ignored by serde.

// TODO: add a way for the user to specify which trait must be derived for the
// generated structs. For now Serde is used to ensure easy serialization.

quote! {
#[derive(Debug, PartialEq, PartialOrd, Clone, serde::Serialize, serde::Deserialize)]
#[derive(#(#internal_derives,)*)]
pub struct #struct_name<#(#gen_args),*> {
#(pub #members),*
}
}
} else {
quote! {
#[derive(Debug, PartialEq, PartialOrd, Clone, serde::Serialize, serde::Deserialize)]
#[derive(#(#internal_derives,)*)]
pub struct #struct_name {
#(pub #members),*
}
Expand Down
16 changes: 12 additions & 4 deletions crates/rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ pub struct Abigen {
pub types_aliases: HashMap<String, String>,
/// The version of transaction to be executed.
pub execution_version: ExecutionVersion,
/// Derives to be added to the generated types.
pub derives: Vec<String>,
}

impl Abigen {
Expand All @@ -83,6 +85,7 @@ impl Abigen {
abi_source: Utf8PathBuf::from(abi_source),
types_aliases: HashMap::new(),
execution_version: ExecutionVersion::V1,
derives: vec![],
}
}

Expand Down Expand Up @@ -112,8 +115,12 @@ impl Abigen {

match AbiParser::tokens_from_abi_string(&file_content, &self.types_aliases) {
Ok(tokens) => {
let expanded =
abi_to_tokenstream(&self.contract_name, &tokens, self.execution_version);
let expanded = abi_to_tokenstream(
&self.contract_name,
&tokens,
self.execution_version,
&self.derives,
);

Ok(ContractBindings {
name: self.contract_name.clone(),
Expand All @@ -140,6 +147,7 @@ pub fn abi_to_tokenstream(
contract_name: &str,
abi_tokens: &TokenizedAbi,
execution_version: ExecutionVersion,
derives: &[String],
) -> TokenStream2 {
let contract_name = utils::str_to_ident(contract_name);

Expand All @@ -149,13 +157,13 @@ pub fn abi_to_tokenstream(

for s in &abi_tokens.structs {
let s_composite = s.to_composite().expect("composite expected");
tokens.push(CairoStruct::expand_decl(s_composite));
tokens.push(CairoStruct::expand_decl(s_composite, derives));
tokens.push(CairoStruct::expand_impl(s_composite));
}

for e in &abi_tokens.enums {
let e_composite = e.to_composite().expect("composite expected");
tokens.push(CairoEnum::expand_decl(e_composite));
tokens.push(CairoEnum::expand_decl(e_composite, derives));
tokens.push(CairoEnum::expand_impl(e_composite));

tokens.push(CairoEnumEvent::expand(
Expand Down
22 changes: 22 additions & 0 deletions examples/structs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use cainome::rs::abigen;

use starknet::core::types::Felt;

abigen!(
MyContract,
"./contracts/abi/gen.abi.json",
derives(Debug, Clone)
);

#[tokio::main]
async fn main() {
let s = MyStruct::<Felt> {
f1: Felt::ONE,
f2: Felt::TWO,
f3: Felt::THREE,
};

println!("{:?}", s);

let _s2 = s.clone();
}
5 changes: 5 additions & 0 deletions src/bin/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ pub struct CainomeArgs {
#[arg(value_name = "EXECUTION_VERSION")]
#[arg(help = "The execution version to use. Supported values are 'v1', 'V1', 'v3', or 'V3'.")]
pub execution_version: ExecutionVersion,

#[arg(long)]
#[arg(value_name = "DERIVES")]
#[arg(help = "Derives to be added to the generated types.")]
pub derives: Option<Vec<String>>,
}

#[derive(Debug, Args, Clone)]
Expand Down
1 change: 1 addition & 0 deletions src/bin/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ async fn main() -> CainomeCliResult<()> {
output_dir: args.output_dir,
contracts,
execution_version: args.execution_version,
derives: args.derives.unwrap_or_default(),
})
.await?;

Expand Down
1 change: 1 addition & 0 deletions src/bin/cli/plugins/builtins/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl BuiltinPlugin for RustPlugin {
&contract_name,
&contract.tokens,
input.execution_version,
&input.derives,
);
let filename = format!(
"{}.rs",
Expand Down
1 change: 1 addition & 0 deletions src/bin/cli/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct PluginInput {
pub output_dir: Utf8PathBuf,
pub contracts: Vec<ContractData>,
pub execution_version: ExecutionVersion,
pub derives: Vec<String>,
}

#[derive(Debug)]
Expand Down

0 comments on commit 2433cc3

Please sign in to comment.