Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions contracts/src/gen.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ mod gen {
Eleven: (felt252, u8, u128),
}


#[external(v0)]
fn func1(ref self: ContractState, a: MyStruct<felt252>) {
self.v1.write(a.f1);
Expand Down
21 changes: 18 additions & 3 deletions crates/cairo-serde-derive/src/derive_enum.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{DataEnum, Ident, Type, Variant};
use syn::{DataEnum, Generics, Ident, Type, Variant};
use unzip_n::unzip_n;

pub fn derive_enum(ident: Ident, data: DataEnum) -> TokenStream {
pub fn derive_enum(ident: Ident, generics: Generics, data: DataEnum) -> TokenStream {
let matches = &data
.variants
.iter()
Expand Down Expand Up @@ -58,11 +58,26 @@ pub fn derive_enum(ident: Ident, data: DataEnum) -> TokenStream {
}
};

let mut generic_contraints_list = vec![];
for param in generics.type_params() {
generic_contraints_list.push(quote! {
#param: ::cainome_cairo_serde::CairoSerde<RustType = #param>
});
}

let generic_contraints = if generic_contraints_list.is_empty() {
quote! {}
} else {
quote! { where #(#generic_contraints_list),* }
};

// There is no easy way to check for the members being staticaly sized at compile time.
// Any of the members of the composite type can have a dynamic size.
// This is why we return `None` for the `SERIALIZED_SIZE` constant.
let output = quote! {
impl ::cainome_cairo_serde::CairoSerde for #ident {
impl #generics ::cainome_cairo_serde::CairoSerde for #ident #generics
#generic_contraints
{
type RustType = Self;

const SERIALIZED_SIZE: Option<usize> = None;
Expand Down
21 changes: 18 additions & 3 deletions crates/cairo-serde-derive/src/derive_struct.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{DataStruct, Ident, Type};
use syn::{DataStruct, Generics, Ident, Type};

pub fn derive_struct(ident: Ident, data: DataStruct) -> TokenStream {
pub fn derive_struct(ident: Ident, generics: Generics, data: DataStruct) -> TokenStream {
let (fields, types) = fields_accessors_and_types(&data.fields);

let cairo_serialized_size = quote! {
Expand Down Expand Up @@ -39,11 +39,26 @@ pub fn derive_struct(ident: Ident, data: DataStruct) -> TokenStream {
}
};

let mut generic_contraint_list = vec![];
for param in generics.type_params() {
generic_contraint_list.push(quote! {
#param: ::cainome_cairo_serde::CairoSerde<RustType = #param>
});
}

let generic_contraints = if generic_contraint_list.is_empty() {
quote! {}
} else {
quote! { where #(#generic_contraint_list),* }
};

// There is no easy way to check for the members being staticaly sized at compile time.
// Any of the members of the composite type can have a dynamic size.
// This is why we return `None` for the `SERIALIZED_SIZE` constant.
let output = quote! {
impl ::cainome_cairo_serde::CairoSerde for #ident {
impl #generics ::cainome_cairo_serde::CairoSerde for #ident #generics
#generic_contraints
{
type RustType = Self;

const SERIALIZED_SIZE: Option<usize> = None;
Expand Down
11 changes: 8 additions & 3 deletions crates/cairo-serde-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ mod derive_struct;

#[proc_macro_derive(CairoSerde)]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
let DeriveInput {
ident,
generics,
data,
..
} = parse_macro_input!(input);

let output = match data {
Data::Struct(data) => derive_struct::derive_struct(ident, data),
Data::Enum(data) => derive_enum::derive_enum(ident, data),
Data::Struct(data) => derive_struct::derive_struct(ident, generics, data),
Data::Enum(data) => derive_enum::derive_enum(ident, generics, data),
Data::Union(_) => panic!("Unions are not supported for the cairo_serde_derive!"),
};

Expand Down
43 changes: 20 additions & 23 deletions crates/integration-tests/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use cainome_parser::{AbiParser, ParserContext};

use cainome_rs::expand::generic_resolver::GenericResolverFromMapping;
use cainome_rs::expand::{ExpansionContext, ExpansionContextFactory};
use starknet::core::types::contract::legacy::{LegacyContractClass, RawLegacyAbiEntry};
use starknet::core::types::contract::{AbiEntry, SierraClass};
Expand Down Expand Up @@ -29,14 +30,18 @@ fn legacy_expand(out_name: &str, ctx: &ExpansionContext) {

let abi = read_file_legacy(ctx.contract_source.as_ref());

let ctx = ctx.clone();

let registry =
AbiParser::build_registry(abi, ParserContext::from(&ctx)).expect("failed tokens parsing");
AbiParser::build_registry(abi, ParserContext::from(ctx)).expect("failed tokens parsing");

let expanded = cainome_rs::abi_to_tokenstream(&registry, &ctx).expect("expansion failed");
let expanded = cainome_rs::abi_to_tokenstream(&registry, ctx).expect("expansion failed");

let syntax_tree = syn::parse2::<syn::File>(expanded).unwrap();
let debug_data = expanded.to_string();

let syntax_tree = syn::parse2::<syn::File>(expanded)
.inspect_err(|err| {
println!("cargo:trace=Error expanding {err} code to: \n\n{debug_data}\n\n");
})
.unwrap();
let s = prettyplease::unparse(&syntax_tree);

let content = format!(
Expand Down Expand Up @@ -67,6 +72,7 @@ fn read_file(file_path: &str) -> Vec<AbiEntry> {
fn expand(out_name: &str, ctx: &ExpansionContext) {
let cwd = std::env::current_dir().unwrap();
println!("cargo:debug=Current working directory: {cwd:?}");
let path = cwd.to_str().unwrap();

let abi = read_file(ctx.contract_source.as_ref());

Expand All @@ -82,8 +88,6 @@ fn expand(out_name: &str, ctx: &ExpansionContext) {
"// ****\n// Auto-generated by cainome do not edit.\n// ****\n\n#![allow(clippy::all)]\n#![allow(warnings)]\n\n{s}",
);

let path = cwd.to_str().unwrap();

println!("cargo:trace=Writing expanded code to: {path}/{out_name}");

fs::write(format!("{path}/{out_name}"), content).unwrap()
Expand All @@ -96,7 +100,6 @@ fn main() {
.with_contract_name("MyContract")
.with_derives(["Debug"])
.with_cainome_serde_path("cainome_cairo_serde")
// .with_add_deployment(false)
.build(),
);
expand(
Expand All @@ -112,18 +115,12 @@ fn main() {
"serde::Serialize",
"serde::Deserialize",
])
.with_aliases(HashMap::from([
(
"contracts::gen::gen::MyStruct::<core::felt252>".to_string(),
"contracts::gen::gen::MyStructFelt".to_string(),
),
(
"contracts::gen::gen::MyStruct::<core::integer::u256>".to_string(),
"contracts::gen::gen::MyStructFeltU256".to_string(),
),
]))
.with_generic_resolver(GenericResolverFromMapping::new(
vec![("contracts::gen::gen::MyStruct", "f2", "A")], //nowrap
))
.build(),
);

expand(
"./src/bindings/components_events_flat.rs",
&ExpansionContextFactory::new("../../contracts/abi/components.abi.json")
Expand Down Expand Up @@ -209,11 +206,6 @@ fn main() {
"contracts::abicov::structs::GenericOne::<core::felt252>".to_string(),
"crate::test_substitutions::GenericOneFelt".to_string(),
),
// (
// "contracts::abicov::structs::GenericOne::<core::felt252>".to_string(),
// "crate::test_substitutions::GenericOne::<starknet::core::types::Felt>"
// .to_string(),
// ),
(
"contracts::abicov::structs::GenericOne::<core::integer::u256>".to_string(),
"crate::test_substitutions::GenericOneu256".to_string(),
Expand All @@ -228,6 +220,11 @@ fn main() {
"crate::test_substitutions::GenericOneSpanFelt".to_string(),
),
]))
.with_generic_resolver(GenericResolverFromMapping::new(vec![
("contracts::abicov::structs::GenericTwo", "a", "A"), //nowrap
("contracts::abicov::structs::GenericTwo", "b", "B"), //nowrap
("contracts::abicov::structs::GenericOne", "a", "A"),
]))
.build(),
);
}
Loading
Loading