Skip to content

Commit dc9709d

Browse files
committed
refactor(derive): reorganize the code a little bit
1 parent 5a6ad8f commit dc9709d

File tree

1 file changed

+68
-52
lines changed

1 file changed

+68
-52
lines changed

napi-derive/src/lib.rs

Lines changed: 68 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ extern crate quote;
66
extern crate syn;
77

88
use proc_macro::TokenStream;
9+
use quote::Tokens;
10+
use syn::{Body, DeriveInput, VariantData};
911

1012
#[proc_macro_derive(NapiArgs)]
1113
pub fn napi_args(input: TokenStream) -> TokenStream {
@@ -16,63 +18,18 @@ pub fn napi_args(input: TokenStream) -> TokenStream {
1618
}
1719
}
1820

19-
fn impl_napi_args(
20-
ast: &syn::DeriveInput,
21-
) -> Result<quote::Tokens, &'static str> {
21+
fn impl_napi_args(ast: &DeriveInput) -> Result<Tokens, &'static str> {
2222
let name = &ast.ident;
2323

2424
let variant_data = match ast.body {
25-
syn::Body::Struct(ref data) => data,
25+
Body::Struct(ref data) => data,
2626
_ => return Err("NapiArgs can only be derived for structs"),
2727
};
2828

29-
let (init_list, count, imports) = match *variant_data {
30-
syn::VariantData::Struct(ref fields) => {
31-
let inner = fields
32-
.iter()
33-
.enumerate()
34-
.map(|(idx, field)| {
35-
let ident = field.clone().ident.unwrap();
36-
quote! {
37-
#ident: <_ as NapiValue>::from_sys_checked(
38-
env,
39-
argv[#idx],
40-
)?
41-
}
42-
})
43-
.collect::<Vec<_>>();
44-
45-
let outer = quote! {
46-
{ #(#inner),* }
47-
};
48-
49-
let imports = quote! {
50-
use ::napi::NapiValue;
51-
};
29+
let count = args_count(variant_data);
30+
let (init_list, imports) = gen_args_code(variant_data);
5231

53-
(Some(outer), fields.len(), imports)
54-
}
55-
56-
syn::VariantData::Tuple(ref fields) => {
57-
let inner = (0..fields.len())
58-
.map(|idx| {
59-
quote! {
60-
<_ as NapiValue>::from_sys_checked(env, argv[#idx])?
61-
}
62-
})
63-
.collect::<Vec<_>>();
64-
65-
let outer = quote! {
66-
( #(#inner),* )
67-
};
68-
69-
(Some(outer), fields.len(), quote! {})
70-
}
71-
72-
syn::VariantData::Unit => (None, 0, quote! {}),
73-
};
74-
75-
let construct = if let Some(init_list) = init_list {
32+
let initializer = if let Some(init_list) = init_list {
7633
quote! { #name #init_list }
7734
} else {
7835
quote! { #name }
@@ -81,7 +38,7 @@ fn impl_napi_args(
8138
let (gen_lifetime, ref_lifetime) = if count > 0 {
8239
(quote! { <'env> }, quote! { 'env })
8340
} else {
84-
(quote! {}, quote! {})
41+
(quote!{}, quote!{})
8542
};
8643

8744
Ok(quote! {
@@ -120,8 +77,67 @@ fn impl_napi_args(
12077
return Err(NapiError::type_error(env, &message));
12178
}
12279

123-
Ok(#construct)
80+
Ok(#initializer)
12481
}
12582
}
12683
})
12784
}
85+
86+
fn args_count(variant_data: &VariantData) -> usize {
87+
match *variant_data {
88+
VariantData::Struct(ref fields) | VariantData::Tuple(ref fields) => {
89+
fields.len()
90+
}
91+
VariantData::Unit => 0,
92+
}
93+
}
94+
95+
fn gen_args_code(
96+
variant_data: &VariantData,
97+
) -> (Option<Tokens>, Option<Tokens>) {
98+
match *variant_data {
99+
VariantData::Struct(ref fields) => {
100+
let inner = fields
101+
.iter()
102+
.enumerate()
103+
.map(|(idx, field)| {
104+
let ident = field.clone().ident.unwrap();
105+
quote! {
106+
#ident: <_ as NapiValue>::from_sys_checked(
107+
env,
108+
argv[#idx],
109+
)?
110+
}
111+
})
112+
.collect::<Vec<_>>();
113+
114+
let outer = quote! {
115+
{ #(#inner),* }
116+
};
117+
118+
let imports = quote! {
119+
use ::napi::NapiValue;
120+
};
121+
122+
(Some(outer), Some(imports))
123+
}
124+
125+
VariantData::Tuple(ref fields) => {
126+
let inner = (0..fields.len())
127+
.map(|idx| {
128+
quote! {
129+
<_ as NapiValue>::from_sys_checked(env, argv[#idx])?
130+
}
131+
})
132+
.collect::<Vec<_>>();
133+
134+
let outer = quote! {
135+
( #(#inner),* )
136+
};
137+
138+
(Some(outer), None)
139+
}
140+
141+
VariantData::Unit => (None, None),
142+
}
143+
}

0 commit comments

Comments
 (0)