feat (macro-rs): convert `&[T]` to `Vec<T>`

This commit is contained in:
sup39 2024-04-12 04:31:21 +09:00 committed by naskya
parent b6b07d562c
commit 2ba60a3b40
No known key found for this signature in database
GPG Key ID: 712D413B3A9FED5C
1 changed files with 55 additions and 8 deletions

View File

@ -16,6 +16,7 @@ pub fn dummy_macro(
///
/// The types of the function arguments is converted with following rules:
/// - `&str` and `&mut str` are converted to `String`
/// - `&[T]` and `&mut [T]` are converted to `Vec<T>`
/// - `&T` and `&mut T` are converted to `T`
/// - Other `T` remains `T`
///
@ -67,6 +68,28 @@ pub fn dummy_macro(
/// }
/// ```
///
/// ## Example with `&[String]` argument
/// ```
/// # mod napi_derive { pub use macro_rs::dummy_macro as napi; } // FIXME
/// #[macro_rs::napi]
/// pub fn string_array_length(array: &[String]) -> u32 {
/// array.len() as u32
/// }
/// ```
///
/// generates
///
/// ```
/// # mod napi_derive { pub use macro_rs::dummy_macro as napi; } // FIXME
/// # pub fn string_array_length(array: &[String]) -> u32 {
/// # array.len() as u32
/// # }
/// #[napi_derive::napi(js_name = "stringArrayLength")]
/// pub fn string_array_length_napi(array: Vec<String>) -> u32 {
/// string_array_length(&array)
/// }
/// ```
///
/// ## Example with `Result<T, E>` return type
/// ```
/// # mod napi_derive { pub use macro_rs::dummy_macro as napi; } // FIXME
@ -220,14 +243,21 @@ fn napi_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
// (1) add `mut` token to `&mut` type
ident.mutability = r.mutability;
// (2) remove reference
let elem_tokens = r.elem.to_token_stream();
*arg.ty =
syn::Type::Verbatim(match elem_tokens.to_string().as_str() {
// &str => String
"str" => quote! { String },
// &T => T
_ => elem_tokens,
});
*arg.ty = syn::Type::Verbatim(match &*r.elem {
syn::Type::Slice(slice) => {
let ty = &*slice.elem;
quote! { Vec<#ty> }
}
_ => {
let elem_tokens = r.elem.to_token_stream();
match elem_tokens.to_string().as_str() {
// &str => String
"str" => quote! { String },
// &T => T
_ => elem_tokens,
}
}
});
// return arguments in function call
tokens
@ -374,4 +404,21 @@ mod tests {
}
)
}
#[test]
fn slice_type() {
test_macro!(
quote! {
pub fn string_array_length(array: &[String]) -> u32 {
array.len() as u32
}
},
quote! {
#[napi_derive::napi(js_name = "stringArrayLength")]
pub fn string_array_length_napi(array: Vec<String>) -> u32 {
string_array_length(&array)
}
}
)
}
}