Refactor `format_namespace_bound_cc_tokens` in functional style.
PiperOrigin-RevId: 500270458
diff --git a/common/code_gen_utils.rs b/common/code_gen_utils.rs
index 290c4d2..e3b895b 100644
--- a/common/code_gen_utils.rs
+++ b/common/code_gen_utils.rs
@@ -124,32 +124,34 @@
pub fn format_namespace_bound_cc_tokens(
iter: impl IntoIterator<Item = (NamespaceQualifier, TokenStream)>,
) -> TokenStream {
- let mut iter = iter.into_iter().peekable();
- let mut tokens_in_curr_ns = Vec::with_capacity(iter.size_hint().0);
- let mut result = TokenStream::default();
- while let Some((curr_ns, tokens)) = iter.next() {
- tokens_in_curr_ns.push(tokens);
+ let iter = iter
+ .into_iter()
+ .coalesce(|(ns1, mut tokens1), (ns2, tokens2)| {
+ // Coallesce tokens if subsequent items belong to the same namespace.
+ if ns1 == ns2 {
+ tokens1.extend(tokens2);
+ Ok((ns1, tokens1))
+ } else {
+ Err(((ns1, tokens1), (ns2, tokens2)))
+ }
+ })
+ .map(|(ns, tokens)| {
+ ns.format_with_cc_body(tokens).unwrap_or_else(|err| {
+ let name = ns.0.iter().join("::");
+ let err = format!("Failed to format namespace name `{name}`: {err}");
+ quote! { __COMMENT__ #err }
+ })
+ });
- // Flush `tokens_in_curr_ns` when at the end of the current namespace.
- let next_ns = iter.peek().map(|(next_ns, _)| next_ns);
- if next_ns != Some(&curr_ns) {
- let tokens_in_curr_ns = tokens_in_curr_ns.drain(..);
- let curr_ns = curr_ns
- .format_with_cc_body(quote! { #(#tokens_in_curr_ns)* })
- .unwrap_or_else(|err| {
- let name = curr_ns.0.iter().join("::");
- let err = format!("Failed to format namespace name `{name}`: {err}");
- quote!{ __COMMENT__ #err }
- });
- result.extend(curr_ns);
- }
+ // Using fully-qualified syntax to avoid the warning that `intersperse`
+ // may be added to the standard library in the future.
+ //
+ // TODO(https://github.com/rust-lang/rust/issues/79524): Use `.intersperse(...)` syntax once
+ // 1) this stdlib feature gets stabilized and
+ // 2) the method with conflicting name gets removed from `itertools`.
+ let iter = itertools::Itertools::intersperse(iter, quote! { __NEWLINE__ __NEWLINE__ });
- // Separate namespaces with a single empty line.
- if iter.peek().is_some() {
- result.extend(quote! { __NEWLINE__ __NEWLINE__ });
- }
- }
- result
+ iter.collect()
}
/// `CcInclude` represents a single `#include ...` directive in C++.