Use js_sys::Array, generate _n methods for ergonomics

This commit is contained in:
Anton Danilkin 2018-09-11 00:37:59 +03:00
parent 14eb317509
commit 9f4ed536df
3 changed files with 53 additions and 36 deletions

View File

@ -95,7 +95,19 @@ fn optional_and_union_arguments() {
#[wasm_bindgen_test] #[wasm_bindgen_test]
fn variadic() { fn variadic() {
let f = Variadic::new().unwrap(); let f = Variadic::new().unwrap();
assert_eq!(f.sum(Box::new([1, 2, 3, 4, 5])), 15); assert_eq!(f.sum_5(1, 2, 3, 4, 5), 15);
assert_eq!(
f.sum(
&::js_sys::Array::of5(
&JsValue::from_f64(1f64),
&JsValue::from_f64(2f64),
&JsValue::from_f64(3f64),
&JsValue::from_f64(4f64),
&JsValue::from_f64(5f64),
)
),
15
);
} }
#[wasm_bindgen_test] #[wasm_bindgen_test]

View File

@ -137,8 +137,8 @@ fn builtin_idents() -> BTreeSet<Ident> {
BTreeSet::from_iter( BTreeSet::from_iter(
vec![ vec![
"str", "char", "bool", "JsValue", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "str", "char", "bool", "JsValue", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64",
"usize", "isize", "f32", "f64", "Result", "String", "Box", "Vec", "Option", "usize", "isize", "f32", "f64", "Result", "String", "Vec", "Option",
"ArrayBuffer", "Object", "Promise", "Function", "Array", "ArrayBuffer", "Object", "Promise", "Function",
].into_iter() ].into_iter()
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())), .map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
) )

View File

@ -172,24 +172,6 @@ pub(crate) fn slice_ty(t: syn::Type) -> syn::Type {
}.into() }.into()
} }
/// From `T` create `Box<T>`.
pub(crate) fn box_ty(t: syn::Type) -> syn::Type {
let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
colon2_token: None,
lt_token: Default::default(),
args: FromIterator::from_iter(vec![
syn::GenericArgument::Type(t),
]),
gt_token: Default::default(),
});
let ident = raw_ident("Box");
let seg = syn::PathSegment { ident, arguments };
let path: syn::Path = seg.into();
let ty = syn::TypePath { qself: None, path };
ty.into()
}
/// From `T` create `Vec<T>`. /// From `T` create `Vec<T>`.
pub(crate) fn vec_ty(t: syn::Type) -> syn::Type { pub(crate) fn vec_ty(t: syn::Type) -> syn::Type {
let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
@ -279,16 +261,8 @@ impl<'src> FirstPassRecord<'src> {
} }
}; };
let syn_type = if variadic && i == arguments_count - 1 { let syn_type = if variadic && i == arguments_count - 1 {
// Blacklist unsupported slice types let path = vec![rust_ident("js_sys"), rust_ident("Array")];
match idl_type { shared_ref(leading_colon_path_ty(path), false)
| IdlType::DomString
| IdlType::ByteString
| IdlType::UsvString => return None,
IdlType::Interface(..) => return None,
_ => box_ty(slice_ty(syn_type))
}
} else { } else {
syn_type syn_type
}; };
@ -603,18 +577,49 @@ impl<'src> FirstPassRecord<'src> {
rust_name.push_str(&snake_case_ident(arg_name)); rust_name.push_str(&snake_case_ident(arg_name));
} }
} }
let structural = force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs);
let catch = force_throws || throws(&signature.orig.attrs);
let variadic = signature.args.len() == signature.orig.args.len()
&& signature.orig.args.last().map(|arg| arg.variadic).unwrap_or(false);
if variadic {
for i in 0..=7 {
ret.extend(self.create_one_function(
name,
&format!("{}_{}", rust_name, i),
signature.args[..signature.args.len() - 1].iter()
.zip(&signature.orig.args)
.map(|(idl_type, orig_arg)| (orig_arg.name.to_string(), idl_type))
.chain(
(1..=i)
.map(|j| {
let idl_type = &signature.args[signature.args.len() - 1];
let name = signature.orig.args[signature.args.len() - 1].name;
(format!("{}_{}", name, j), idl_type)
})
)
.collect::<Vec<_>>()
.iter()
.map(|(name, idl_type)| (&name[..], idl_type.clone())),
&ret_ty,
kind.clone(),
structural,
catch,
false,
None,
));
}
}
ret.extend(self.create_one_function( ret.extend(self.create_one_function(
name, name,
&rust_name, &rust_name,
signature.args.iter() signature.args.iter()
.zip(&signature.orig.args) .zip(&signature.orig.args)
.map(|(ty, orig_arg)| (orig_arg.name, ty)), .map(|(idl_type, orig_arg)| (orig_arg.name, idl_type)),
&ret_ty, &ret_ty,
kind.clone(), kind.clone(),
force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs), structural,
force_throws || throws(&signature.orig.attrs), catch,
signature.args.len() == signature.orig.args.len() variadic,
&& signature.orig.args.last().map(|arg| arg.variadic).unwrap_or(false),
None, None,
)); ));
} }