use super::arg_def::*;
use super::util::*;
fn arg_serialize_push_single(
type_path_segment: &syn::PathSegment,
arg_accumulator: &proc_macro2::TokenStream,
var_name: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let type_str = type_path_segment.ident.to_string();
match type_str.as_str() {
"Address" | "StorageKey" | "H256" => quote!{
#arg_accumulator.push_bytes(#var_name.as_bytes());
},
"Vec" => {
match &type_path_segment.arguments {
syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments{args, ..}) => {
if args.len() != 1 {
panic!("[callable] Vec type must have exactly 1 generic type argument");
}
if let syn::GenericArgument::Type(vec_type) = args.first().unwrap() {
match vec_type {
syn::Type::Path(type_path) => {
let type_path_segment = type_path.path.segments.last().unwrap().clone();
let type_str = type_path_segment.ident.to_string();
match type_str.as_str() {
"u8" => quote!{
#arg_accumulator.push_bytes(#var_name.as_slice());
},
other_type => panic!("[callable] Unsupported type: Vec<{:?}>", other_type)
}
},
other_type => panic!("[callable] Unsupported Vec generic type: {:?}, not a path", other_type)
}
} else {
panic!("[callable] Vec type arguments must be types")
}
},
_ => panic!("[callable] Vec angle brackets expected")
}
},
"BigInt" =>
panic!("[callable] BigInt arguments not yet supported"),
"BigUint" =>
quote!{
#arg_accumulator.push_bytes(#var_name.to_bytes_be().as_slice());
},
"u64" =>
quote!{
#arg_accumulator.push_u64(#var_name);
},
"i64" =>
quote!{
#arg_accumulator.push_i64(#var_name);
},
"u32" =>
quote!{
#arg_accumulator.push_u32(#var_name);
},
"i32" =>
quote!{
#arg_accumulator.push_i32(#var_name);
},
"usize" =>
quote!{
#arg_accumulator.push_u32(#var_name as u32);
},
"isize" =>
quote!{
#arg_accumulator.push_i32(#var_name as i32);
},
"u8" =>
quote!{
#arg_accumulator.push_byte(#var_name);
},
"i8" =>
quote!{
#arg_accumulator.push_byte(#var_name as u8);
},
other_stype_str => {
panic!("[callable] Unsupported argument type {:?} for arg init snippet", other_stype_str)
}
}
}
pub fn arg_serialize_push(
arg: &MethodArg,
arg_accumulator: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let pat = &arg.pat;
let var_name = quote!{ #pat };
match &arg.ty {
syn::Type::Path(type_path) => {
let type_path_segment = type_path.path.segments.last().unwrap().clone();
arg_serialize_push_single(&type_path_segment, &arg_accumulator, &var_name)
},
syn::Type::Reference(type_reference) => {
if type_reference.mutability.is_some() {
panic!("Mutable references not supported as contract method arguments");
}
match &*type_reference.elem {
syn::Type::Path(type_path) => {
let type_path_segment = type_path.path.segments.last().unwrap().clone();
arg_serialize_push_single(&type_path_segment, arg_accumulator, &var_name)
},
_ => {
panic!("Unsupported reference argument type, reference does not contain type path: {:?}", type_reference)
}
}
},
other_arg => panic!("Unsupported argument type: {:?}, neither path nor reference", other_arg)
}
}
pub fn arg_serialize_push_multi(
arg: &MethodArg,
arg_accumulator: &proc_macro2::TokenStream,
var_name: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {
match &arg.ty {
syn::Type::Path(type_path) => {
let type_path_segment = type_path.path.segments.last().unwrap().clone();
let type_str = type_path_segment.ident.to_string();
match type_str.as_str() {
"Vec" => {
let vec_generic_type_segm = generic_type_single_arg_segment(&"Vec", &type_path_segment);
arg_serialize_push_single(&vec_generic_type_segm, arg_accumulator, var_name)
},
other_stype_str => {
panic!("Unsupported argument type {:?} for multi argument", other_stype_str)
}
}
},
other_arg => panic!("Unsupported argument type: {:?}, neither path nor reference", other_arg)
}
}