Skip to content

Commit ec8a032

Browse files
committed
expose props as idents
1 parent 42ffcc4 commit ec8a032

2 files changed

Lines changed: 63 additions & 33 deletions

File tree

macros/src/props.rs

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,21 @@ impl Props {
171171

172172
let mut let_bindings = Vec::new();
173173

174-
let mut struct_ctor_fvs = Vec::new();
174+
let mut new_decl_args = Vec::new();
175+
let mut new_fvs = Vec::new();
176+
let mut new_ctor_args = Vec::new();
175177

176178
for kv in self.key_values.values() {
179+
let input_field = kv.fv.key_ident()?;
180+
177181
let input_ident = Ident::new(&format!("__i{}", kv.idx), kv.span());
178182
let fn_ident = Ident::new(&format!("__f{}", kv.idx), kv.span());
179183

180184
let input_ty = Ident::new(&format!("__I{}", kv.idx), kv.span());
181185
let fn_ty = Ident::new(&format!("__F{}", kv.idx), kv.span());
182186

183-
let cfg_attr = &kv.cfg_attr;
187+
let cfg_attr = kv.cfg_attr.as_ref();
188+
let invert_cfg_attr = cfg_attr.and_then(|cfg_attr| cfg_attr.invert_cfg());
184189

185190
struct_decl_tys.push(quote!(#input_ty));
186191
struct_decl_tys.push(quote!(#fn_ty));
@@ -191,13 +196,17 @@ impl Props {
191196
impl_struct_tys.push(quote!(#input_ty));
192197
impl_struct_tys.push(quote!(#fn_ty));
193198

194-
struct_decl_fvs.push(quote!(#input_ident: #input_ty));
199+
struct_decl_fvs.push(quote!(#cfg_attr pub(super) #input_field: #input_ty));
200+
if let Some(invert_cfg_attr) = &invert_cfg_attr {
201+
struct_decl_fvs.push(quote!(#invert_cfg_attr #input_field: #input_ty));
202+
}
203+
195204
struct_decl_fvs.push(quote!(#fn_ident: #fn_ty));
196205
struct_decl_markers.push(quote!(#input_ty));
197206
struct_decl_markers.push(quote!(#fn_ty));
198207

199208
let value = &kv.fv.expr;
200-
let value = maybe_cfg(cfg_attr.as_ref(), kv.span(), quote!({#value}));
209+
let value = maybe_cfg(cfg_attr, kv.span(), quote!({#value}));
201210

202211
let_bindings.push(quote!(let #input_ident = { #value }));
203212

@@ -214,40 +223,46 @@ impl Props {
214223

215224
let fn_body = quote!((#key_tokens, #value_tokens));
216225
let fn_body = maybe_cfg_else(
217-
cfg_attr.as_ref(),
226+
cfg_attr,
218227
kv.span(),
219228
fn_body,
220229
quote!(emit::__private::core::unreachable!()),
221230
)?;
222231

223-
struct_ctor_fvs.push(quote!(
224-
#fn_ident: (&#input_ident).__private_infer_input(|#input_ident| #fn_body)
225-
));
226-
struct_ctor_fvs.push(quote!(#input_ident));
232+
new_decl_args.push(quote!(#fn_ident: #fn_ty));
233+
new_decl_args.push(quote!(#input_ident: #input_ty));
234+
235+
new_fvs.push(quote!(#fn_ident));
236+
new_fvs.push(quote!(#input_field: #input_ident));
227237

228-
impl_for_each.push(maybe_cfg(
229-
cfg_attr.as_ref(),
238+
new_ctor_args
239+
.push(quote!((&#input_ident).__private_infer_input(|#input_ident| #fn_body)));
240+
new_ctor_args.push(quote!(#input_ident));
241+
242+
impl_for_each.push(maybe_cfg_else(
243+
cfg_attr,
230244
kv.span(),
231245
quote!(
232246
{
233-
match (self.#fn_ident)(&self.#input_ident) {
247+
match (self.#fn_ident)(&self.#input_field) {
234248
(k, emit::__private::core::option::Option::Some(v)) => for_each(k, v)?,
235249
_ => (),
236250
}
237251
}
238252
),
239-
));
253+
quote!({ let _ = self.#input_field; }),
254+
)?);
240255

241256
impl_to_value.push(maybe_cfg_else(
242-
cfg_attr.as_ref(),
257+
cfg_attr,
243258
kv.span(),
244-
quote!({ (self.#fn_ident)(&self.#input_ident).1.unwrap_or(emit::Value::null()) }),
259+
quote!({ (self.#fn_ident)(&self.#input_field).1.unwrap_or(emit::Value::null()) }),
245260
quote!({ emit::Value::null() }),
246261
)?);
247262
}
248263

249264
struct_decl_fvs.push(quote!(__marker: emit::__private::core::marker::PhantomData<(#(#struct_decl_markers,)*)>));
250-
struct_ctor_fvs.push(quote!(__marker: emit::__private::core::marker::PhantomData));
265+
new_fvs.push(quote!(__marker: emit::__private::core::marker::PhantomData));
251266

252267
let single_impls = if self.key_values.len() == 1 {
253268
Some(quote!(
@@ -265,32 +280,42 @@ impl Props {
265280
#[allow(unused_imports)]
266281
use emit::__private::__PrivateInferInput;
267282

268-
struct __Props<#(#struct_decl_tys,)*> {
269-
#(#struct_decl_fvs,)*
270-
}
283+
mod __props {
284+
pub(super) struct __Props<#(#struct_decl_tys,)*> {
285+
#(#struct_decl_fvs,)*
286+
}
287+
288+
impl<#(#impl_decl_tys,)*> __Props<#(#impl_struct_tys,)*> {
289+
pub(super) fn __new(
290+
#(#new_decl_args,)*
291+
) -> Self {
292+
__Props {
293+
#(#new_fvs,)*
294+
}
295+
}
296+
}
271297

272-
#single_impls
298+
#single_impls
273299

274-
impl<#(#impl_decl_tys,)*> emit::Props for __Props<#(#impl_struct_tys,)*> {
275-
fn for_each<
276-
'kv,
277-
F: emit::__private::core::ops::FnMut(emit::Str<'kv>, emit::Value<'kv>) -> emit::__private::core::ops::ControlFlow<()>,
278-
>(&'kv self, mut for_each: F) -> emit::__private::core::ops::ControlFlow<()> {
279-
#(#impl_for_each)*
300+
impl<#(#impl_decl_tys,)*> emit::Props for __Props<#(#impl_struct_tys,)*> {
301+
fn for_each<
302+
'kv,
303+
F: emit::__private::core::ops::FnMut(emit::Str<'kv>, emit::Value<'kv>) -> emit::__private::core::ops::ControlFlow<()>,
304+
>(&'kv self, mut for_each: F) -> emit::__private::core::ops::ControlFlow<()> {
305+
#(#impl_for_each)*
280306

281-
emit::__private::core::ops::ControlFlow::Continue(())
282-
}
307+
emit::__private::core::ops::ControlFlow::Continue(())
308+
}
283309

284-
fn is_unique(&self) -> bool {
285-
true
310+
fn is_unique(&self) -> bool {
311+
true
312+
}
286313
}
287314
}
288315

289316
#(#let_bindings;)*
290317

291-
__Props {
292-
#(#struct_ctor_fvs,)*
293-
}
318+
__props::__Props::__new(#(#new_ctor_args,)*)
294319
}))
295320
}
296321

test/ui/src/props.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ fn props_basic() {
1515

1616
assert!(props.is_unique());
1717

18+
assert_eq!(1, props.b);
19+
assert_eq!(true, props.a);
20+
assert_eq!(2.0, props.c);
21+
assert_eq!("text", props.d);
22+
1823
assert_eq!(1, props.pull::<i32, _>("b").unwrap());
1924
assert_eq!(true, props.pull::<bool, _>("a").unwrap());
2025
assert_eq!(2.0, props.pull::<f64, _>("c").unwrap());

0 commit comments

Comments
 (0)