def emit_multi_variant(count):
print(
f"""\
// Match {count} fields
(
impl($name:ident, $inner:ty, $default:expr)
"""
)
for i in range(0, count):
index = i + 1
print(
f"""\
$( #[$attr{index}:meta] )*
$field{index}:ident $( = $value{index}:expr )? ,
"""
)
print(
"""\
$(
$( #[$rattr:meta] )*
$frest:ident $( = $frest_val:expr )?
),* $(,)?
) => {\
"""
)
for i in range(0, count):
index = i + 1
if index == 1:
prev = "$default"
else:
prev = f"Self::$field{index - 1}.0 + 1"
print(
f"""\
$( #[$attr{index}] )*
#[allow(non_upper_case_globals)]
pub const $field{index}: Self = Self($crate::__c_enum_impl!(
impl(first_expr) $( $value{index}, )? {prev}));
"""
)
print(
f"""\
$crate::__c_enum_decl_variants!(
impl($name, $inner, Self::$field{count}.0 + 1)
$( $( #[$rattr] )* $frest $( = $frest_val )?, )*
);
}};
"""
)
print(
"""\
/// Helper macro for defining the fields of a c_enum!
///
/// Large enums can easily hit the recursion limit imposed by rustc on macros.
/// This macro defines a bunch of variants which consume a bunch of fields at
/// once with the goal being to reduce the recursion limit to something
/// managable even for large enum definitions.
///
/// This code is generated by scripts/enum-impl.py. Don't edit it manually.
/// Edit the script and regenerate it instead.
#[doc(hidden)]
#[macro_export]
macro_rules! __c_enum_decl_variants {
(impl($name:ident, $inner:ty, $default:expr)) => {};
"""
)
emit_multi_variant(128)
emit_multi_variant(32)
emit_multi_variant(8)
print(
"""\
// Base case
(
impl($name:ident, $inner:ty, $default:expr)
$( #[$fattr:meta] )*
$field:ident $( = $fvalue:expr )?
$( ,
$( #[$rattr:meta] )*
$frest:ident $( = $frest_val:expr )?
)*
$(,)?
) => {
$( #[$fattr] )*
#[allow(non_upper_case_globals)]
pub const $field: Self = Self($crate::__c_enum_impl!(
impl(first_expr) $( $fvalue, )? $default));
$crate::__c_enum_decl_variants!(
impl($name, $inner, Self::$field.0 + 1)
$( $( #[$rattr] )* $frest $( = $frest_val )?, )*
);
}
}\
"""
)