Skip to content

Commit 21f216a

Browse files
asgerfCopilot
andcommitted
yeast-macros: omit empty fields produced by .. splice
When a {..expr} splice in an output template is empty (e.g. from an optional capture that did not match), drop the field entirely rather than emitting an empty named field. This lets a single rule with optional captures replace what used to be two near-identical rules. Also re-renders the corpus to drop the now-suppressed empty fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 1751d70 commit 21f216a

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

shared/yeast-macros/src/parse.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,15 +437,19 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result<TokenStre
437437
.map(::std::convert::Into::<usize>::into)
438438
.collect();
439439
});
440-
field_args.push(quote! { (#field_str, #temp) });
440+
// An empty splice means the field is absent — skip it
441+
// entirely rather than emitting an empty named field.
442+
field_args.push(quote! {
443+
if !#temp.is_empty() { __fields.push((#field_str, #temp)); }
444+
});
441445
continue;
442446
}
443447
}
444448
}
445449

446450
let value = parse_direct_node(tokens, ctx)?;
447451
stmts.push(quote! { let #temp: usize = #value; });
448-
field_args.push(quote! { (#field_str, vec![#temp]) });
452+
field_args.push(quote! { __fields.push((#field_str, vec![#temp])); });
449453
}
450454

451455
// After all named fields, no other tokens are allowed.
@@ -461,7 +465,9 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result<TokenStre
461465
Ok(quote! {
462466
{
463467
#(#stmts)*
464-
#ctx.node(#kind_str, vec![#(#field_args),*])
468+
let mut __fields: Vec<(&str, Vec<usize>)> = Vec::new();
469+
#(#field_args)*
470+
#ctx.node(#kind_str, __fields)
465471
}
466472
})
467473
}

0 commit comments

Comments
 (0)