These are currently implemented via the format!
macro, and is designed to be (hopefully) extensible to more complex expressions.
BMUMO42ICN3GQW77KUE2GTJPOA77SFDXJ4NNDO5NA2VJS267OXZAC
Self::Message(message) => message.value.as_ref().map_or_else(
|| parse_quote! { () },
|pattern| {
let parsed_patterns = pattern.elements.iter().map(match_pattern_element);
parse_quote! { #(#parsed_patterns)+* }
},
),
Self::Message(message) => message
.value
.as_ref()
.map_or_else(|| parse_quote!(()), match_pattern),
fn match_pattern<'resource>(pattern: &'resource Pattern<&'resource str>) -> syn::Expr {
let mut format_body = proc_macro2::TokenStream::new();
let mut format_arguments = proc_macro2::TokenStream::new();
for element in &pattern.elements {
match element {
PatternElement::TextElement { value } => format_body.extend(quote!(#value)),
PatternElement::Placeable { expression } => {
let expression = match_placeable_expression(&expression);
format_body.extend(quote!({}));
format_arguments.extend(quote!(#expression));
}
}
}
fn match_pattern_element<'resource>(
pattern_element: &'resource PatternElement<&'resource str>,
let format_body_literal = proc_macro2::Literal::string(format_body.to_string().as_str());
parse_quote!(format!(#format_body_literal, #format_arguments))
}
fn match_placeable_expression<'resource>(
expression: &'resource Expression<&'resource str>,
) -> syn::Expr {
match expression {
Expression::Select { selector, variants } => match_inline_expression(selector),
Expression::Inline(expression) => match_inline_expression(expression),
}
}
fn match_inline_expression<'resource>(
expression: &'resource InlineExpression<&'resource str>,
match pattern_element {
PatternElement::TextElement { value } => parse_quote! { #value },
match expression {
InlineExpression::StringLiteral { value } => {
let string_literal = proc_macro2::Literal::string(value);
parse_quote!(#string_literal)
}
InlineExpression::NumberLiteral { value } => {
// FIXME: i128 is "good enough" for now but an incorrect representation!
// e.g. decimals not supported
let parsed_value = i128::from_str_radix(value, 10).unwrap();
let number_literal = proc_macro2::Literal::i128_unsuffixed(parsed_value);
parse_quote!(#number_literal)
}