Skip to content

Commit 98c9a98

Browse files
committed
ethabi_derive generates code using into_iterator for array, closes rust-ethereum#45
1 parent 9e874ab commit 98c9a98

18 files changed

+489
-235
lines changed

.editorconfig

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ trim_trailing_whitespace=true
99
max_line_length=120
1010
insert_final_newline=true
1111

12+
[*.json]
13+
indent_style=space
14+
indent_size=4
15+

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
target
22
*.swp
3+
*.swo

cli/src/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ mod tests {
239239

240240
#[test]
241241
fn abi_encode() {
242-
let command = "ethabi encode function ../examples/test.json foo -p 1".split(" ");
242+
let command = "ethabi encode function ../res/test.abi foo -p 1".split(" ");
243243
let expected = "455575780000000000000000000000000000000000000000000000000000000000000001";
244244
assert_eq!(execute(command).unwrap(), expected);
245245
}
@@ -277,14 +277,14 @@ bool false";
277277

278278
#[test]
279279
fn abi_decode() {
280-
let command = "ethabi decode function ../examples/foo.json bar 0000000000000000000000000000000000000000000000000000000000000001".split(" ");
280+
let command = "ethabi decode function ../res/foo.abi bar 0000000000000000000000000000000000000000000000000000000000000001".split(" ");
281281
let expected = "bool true";
282282
assert_eq!(execute(command).unwrap(), expected);
283283
}
284284

285285
#[test]
286286
fn log_decode() {
287-
let command = "ethabi decode log ../examples/event.json Event -l 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000004444444444444444444444444444444444444444".split(" ");
287+
let command = "ethabi decode log ../res/event.abi Event -l 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000004444444444444444444444444444444444444444".split(" ");
288288
let expected =
289289
"a true
290290
b 4444444444444444444444444444444444444444";

derive/src/lib.rs

+59-7
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,29 @@ fn rust_type(input: &ParamType) -> syn::Ident {
182182
}
183183
}
184184

185+
fn template_param_type(input: &ParamType, index: usize) -> syn::Ident {
186+
match *input {
187+
ParamType::Address => format!("T{}: Into<ethabi::Address>", index).into(),
188+
ParamType::Bytes => format!("T{}: Into<ethabi::Bytes>", index).into(),
189+
ParamType::FixedBytes(32) => format!("T{}: Into<ethabi::Hash>", index).into(),
190+
ParamType::FixedBytes(size) => format!("T{}: Into<[u8; {}]>", index, size).into(),
191+
ParamType::Int(_) => format!("T{}: Into<ethabi::Int>", index).into(),
192+
ParamType::Uint(_) => format!("T{}: Into<ethabi::Uint>", index).into(),
193+
ParamType::Bool => format!("T{}: Into<bool>", index).into(),
194+
ParamType::String => format!("T{}: Into<String>", index).into(),
195+
ParamType::Array(ref kind) => format!("T{}: IntoIterator<Item = U{}>, U{}: Into<{}>", index, index, index, rust_type(&*kind)).into(),
196+
ParamType::FixedArray(ref kind, size) => format!("T{}: Into<[U{}; {}]>, U{}: Into<{}>", index, index, size, index, rust_type(&*kind)).into(),
197+
}
198+
}
199+
200+
fn from_template_param(input: &ParamType, name: &syn::Ident) -> syn::Ident {
201+
match *input {
202+
ParamType::Array(_) => format!("{}.into_iter().map(Into::into).collect::<Vec<_>>()", name).into(),
203+
ParamType::FixedArray(_, _) => format!("(Box::new({}.into()) as Box<[_]>).into_vec().into_iter().map(Into::into).collect::<Vec<_>>()", name).into(),
204+
_ => format!("{}.into()", name).into(),
205+
}
206+
}
207+
185208
fn to_token(name: &syn::Ident, kind: &ParamType) -> quote::Tokens {
186209
match *kind {
187210
ParamType::Address => quote! { ethabi::Token::Address(#name) },
@@ -208,7 +231,7 @@ fn to_token(name: &syn::Ident, kind: &ParamType) -> quote::Tokens {
208231
quote! {
209232
// note the double {{
210233
{
211-
let v = #name.to_vec().into_iter().map(|#inner_name| #inner_loop).collect();
234+
let v = #name.into_iter().map(|#inner_name| #inner_loop).collect();
212235
ethabi::Token::FixedArray(v)
213236
}
214237
}
@@ -271,6 +294,7 @@ fn impl_contract_event(event: &Event) -> quote::Tokens {
271294
}
272295

273296
fn impl_contract_constructor(constructor: &Constructor) -> quote::Tokens {
297+
// [param0, hello_world, param2]
274298
let names: Vec<_> = constructor.inputs
275299
.iter()
276300
.enumerate()
@@ -279,21 +303,36 @@ fn impl_contract_constructor(constructor: &Constructor) -> quote::Tokens {
279303
} else {
280304
param.name.to_snake_case().into()
281305
}).collect();
306+
307+
// [Uint, Bytes, Vec<Uint>]
282308
let kinds: Vec<_> = constructor.inputs
283309
.iter()
284310
.map(|param| rust_type(&param.kind))
285311
.collect();
312+
313+
// [T0, T1, T2]
286314
let template_names: Vec<_> = kinds.iter().enumerate()
287315
.map(|(index, _)| syn::Ident::new(format!("T{}", index)))
288316
.collect();
289-
let template_params: Vec<_> = kinds.iter().zip(template_names.iter())
290-
.map(|(kind, template_name)| quote! { #template_name: Into<#kind> })
317+
318+
// [T0: Into<Uint>, T1: Into<Bytes>, T2: Into<Vec<Uint>>]
319+
//let template_params: Vec<_> = kinds.iter().zip(template_names.iter())
320+
//.map(|(kind, template_name)| quote! { #template_name: Into<#kind> })
321+
//.collect();
322+
323+
// [T0: Into<Uint>, T1: Into<Bytes>, T2: IntoIterator<Item = U2>, U2 = Into<Uint>]
324+
let template_params: Vec<_> = constructor.inputs.iter().enumerate()
325+
.map(|(index, param)| template_param_type(&param.kind, index))
291326
.collect();
327+
328+
// [param0: T0, hello_world: T1, param2: T2]
292329
let params: Vec<_> = names.iter().zip(template_names.iter())
293330
.map(|(param_name, template_name)| quote! { #param_name: #template_name })
294331
.collect();
332+
333+
// [Token::Uint(param0.into()), Token::Bytes(hello_world.into()), Token::Array(param2.into())]
295334
let usage: Vec<_> = names.iter().zip(constructor.inputs.iter())
296-
.map(|(param_name, param)| to_token(&format!("{}.into()", param_name).into(), &param.kind))
335+
.map(|(param_name, param)| to_token(&from_template_param(&param.kind, param_name), &param.kind))
297336
.collect();
298337

299338
quote! {
@@ -381,6 +420,7 @@ fn declare_events(event: &Event) -> quote::Tokens {
381420
.map(|param| rust_type(&param.kind))
382421
.collect();
383422

423+
// [T0, T1, T2]
384424
let template_names: Vec<_> = topic_kinds.iter().enumerate()
385425
.map(|(index, _)| syn::Ident::new(format!("T{}", index)))
386426
.collect();
@@ -440,6 +480,8 @@ fn declare_events(event: &Event) -> quote::Tokens {
440480

441481
fn declare_functions(function: &Function) -> quote::Tokens {
442482
let name = syn::Ident::new(function.name.to_camel_case());
483+
484+
// [param0, hello_world, param2]
443485
let names: Vec<_> = function.inputs
444486
.iter()
445487
.enumerate()
@@ -448,21 +490,31 @@ fn declare_functions(function: &Function) -> quote::Tokens {
448490
} else {
449491
param.name.to_snake_case().into()
450492
}).collect();
493+
494+
// [Uint, Bytes, Vec<Uint>]
451495
let kinds: Vec<_> = function.inputs
452496
.iter()
453497
.map(|param| rust_type(&param.kind))
454498
.collect();
499+
500+
// [T0, T1, T2]
455501
let template_names: Vec<_> = kinds.iter().enumerate()
456502
.map(|(index, _)| syn::Ident::new(format!("T{}", index)))
457503
.collect();
458-
let template_params: Vec<_> = kinds.iter().zip(template_names.iter())
459-
.map(|(kind, template_name)| quote! { #template_name: Into<#kind> })
504+
505+
// [T0: Into<Uint>, T1: Into<Bytes>, T2: IntoIterator<Item = U2>, U2 = Into<Uint>]
506+
let template_params: Vec<_> = function.inputs.iter().enumerate()
507+
.map(|(index, param)| template_param_type(&param.kind, index))
460508
.collect();
509+
510+
// [param0: T0, hello_world: T1, param2: T2]
461511
let params: Vec<_> = names.iter().zip(template_names.iter())
462512
.map(|(param_name, template_name)| quote! { #param_name: #template_name })
463513
.collect();
514+
515+
// [Token::Uint(param0.into()), Token::Bytes(hello_world.into()), Token::Array(param2.into_iter().map(Into::into).collect())]
464516
let usage: Vec<_> = names.iter().zip(function.inputs.iter())
465-
.map(|(param_name, param)| to_token(&format!("{}.into()", param_name).into(), &param.kind))
517+
.map(|(param_name, param)| to_token(&from_template_param(&param.kind, param_name), &param.kind))
466518
.collect();
467519

468520
let output_impl = if !function.constant {

examples/con.json

-7
This file was deleted.

examples/eip20.json

-163
This file was deleted.

examples/event.json

-14
This file was deleted.

examples/foo.json

-13
This file was deleted.

examples/test.json

-9
This file was deleted.

0 commit comments

Comments
 (0)