Skip to content

Commit 0f31158

Browse files
authored
feat(sol!)!: gen unit/tuple structs for call types with 0/1 param (#884)
* feat(`sol!`)!: gen unit/tuple structs for call types with 0/1 param * fix: expand as tuple struct only if single unnamed param
1 parent 89a95a2 commit 0f31158

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

crates/sol-macro-expander/src/expand/function.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, function: &ItemFunction) -> Result<TokenS
6262
let call_tuple = expand_tuple_types(parameters.types(), cx).0;
6363
let return_tuple = expand_tuple_types(returns.types(), cx).0;
6464

65-
let converts = expand_from_into_tuples(&call_name, parameters, cx, FieldKind::Original);
65+
let converts = expand_from_into_tuples(&call_name, parameters, cx, FieldKind::Deconstruct);
6666
let return_converts = expand_from_into_tuples(&return_name, returns, cx, FieldKind::Original);
6767

6868
let signature = cx.function_signature(function);
6969
let selector = crate::utils::selector(&signature);
70-
let tokenize_impl = expand_tokenize(parameters, cx, FieldKind::Original);
70+
let tokenize_impl = expand_tokenize(parameters, cx, FieldKind::Deconstruct);
7171

7272
let call_doc = docs.then(|| {
7373
let selector = hex::encode_prefixed(selector.array.as_slice());
@@ -99,16 +99,31 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, function: &ItemFunction) -> Result<TokenS
9999
}
100100
});
101101

102+
let call_struct = if parameters.is_empty() {
103+
quote! {
104+
pub struct #call_name;
105+
}
106+
} else if parameters.len() == 1 && parameters[0].name.is_none() {
107+
let ty = cx.expand_rust_type(&parameters[0].ty);
108+
quote! {
109+
pub struct #call_name(pub #ty);
110+
}
111+
} else {
112+
quote! {
113+
pub struct #call_name {
114+
#(#call_fields),*
115+
}
116+
}
117+
};
118+
102119
let alloy_sol_types = &cx.crates.sol_types;
103120

104121
let tokens = quote! {
105122
#(#call_attrs)*
106123
#call_doc
107124
#[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)]
108125
#[derive(Clone)]
109-
pub struct #call_name {
110-
#(#call_fields),*
111-
}
126+
#call_struct
112127

113128
#(#return_attrs)*
114129
#return_doc

crates/sol-macro/doctests/function_like.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ fn function() {
2929
let _ = overloaded_0Call {};
3030
assert_call_signature::<overloaded_0Call>("overloaded()");
3131

32-
let _ = overloaded_1Call { _0: U256::from(1) };
32+
let _ = overloaded_1Call(U256::from(1));
3333
assert_call_signature::<overloaded_1Call>("overloaded(uint256)");
3434

35-
let _ = overloaded_2Call { _0: "hello".into() };
35+
let _ = overloaded_2Call("hello".into());
3636
assert_call_signature::<overloaded_2Call>("overloaded(string)");
3737

3838
// Exactly the same as `function variableGetter(uint256) returns (bool)`.

crates/sol-types/tests/macros/sol/mod.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,10 @@ fn getter_names() {
254254
let _ = Getters::valueCall {};
255255
let _ = Getters::valueReturn { value: String::new() };
256256

257-
let _ = Getters::arrayCall { _0: U256::ZERO };
257+
let _ = Getters::arrayCall(U256::ZERO);
258258
let _ = Getters::arrayReturn { _0: String::new() };
259259

260-
let _ = Getters::mapCall { _0: B256::ZERO };
260+
let _ = Getters::mapCall(B256::ZERO);
261261
let _ = Getters::mapReturn { _0: String::new() };
262262

263263
let _ = Getters::mapWithNamesCall { k: B256::ZERO };
@@ -497,17 +497,17 @@ fn rust_keywords() {
497497
bytes32 box;
498498
}
499499

500-
function mod(address impl) returns (bool is, bool fn);
500+
function mod(address impl, address some) returns (bool is, bool fn);
501501
}
502502
}
503503
use r#dyn::*;
504504

505505
let _ = r#const { r#unsafe: true, r#box: Default::default() };
506-
let m = modCall { r#impl: Address::ZERO };
506+
let m = modCall { r#impl: Address::ZERO, some: Address::ZERO };
507507
let _ = dynCalls::r#mod(m);
508508
let _ = modReturn { is: true, r#fn: false };
509509
assert_eq!(r#const::NAME, "const");
510-
assert_eq!(modCall::SIGNATURE, "mod(address)");
510+
assert_eq!(modCall::SIGNATURE, "mod(address,address)");
511511
}
512512

513513
#[test]
@@ -543,7 +543,7 @@ fn most_rust_keywords() {
543543
assert_eq!($raw::NAME, stringify!($kw));
544544
assert_ne!($raw::NAME, stringify!($raw));
545545
assert_eq!(<[<$kw Call>]>::SIGNATURE, concat!(stringify!($kw), "(bytes1)"));
546-
let _ = [<$kw Call>] { $raw: [0u8; 1].into() };
546+
let _ = [<$kw Call>] { $raw: [0u8; 1].into()};
547547
assert_eq!(error::$raw::SIGNATURE, concat!(stringify!($kw), "(bytes2)"));
548548
let _ = error::$raw { $raw: [0u8; 2].into() };
549549
assert_eq!(event::$raw::SIGNATURE, concat!(stringify!($kw), "(bytes3)"));
@@ -914,16 +914,16 @@ fn contract_derive_default() {
914914
sol! {
915915
#[derive(Debug, Default)]
916916
contract MyContract {
917-
function f1();
918-
function f2();
917+
function f1(address);
918+
function f2(address b);
919919
event e1();
920920
event e2();
921921
error c();
922922
}
923923
}
924924

925-
let MyContract::f1Call {} = MyContract::f1Call::default();
926-
let MyContract::f2Call {} = MyContract::f2Call::default();
925+
let MyContract::f1Call(_) = MyContract::f1Call::default();
926+
let MyContract::f2Call { b: _ } = MyContract::f2Call::default();
927927
let MyContract::e1 {} = MyContract::e1::default();
928928
let MyContract::e2 {} = MyContract::e2::default();
929929
#[allow(clippy::default_constructed_unit_structs)]

0 commit comments

Comments
 (0)