Add error handling for common unsupported Rust code

finchie
Apr 2, 2025, 10:03 AM
YZ6PVVQCLWYRFM33CH6BDB7U6BSP5PM5LH3FMKRXV3BH5KCRFM4AC

Dependencies

  • [2] JWZT34UC Add `Localize`` trait bound for each field in the derived item
  • [3] QFPQZR4K Refactor `fluent_embed`
  • [4] XEEXWJLG Add simple end-to-end test for selectors
  • [5] F5LG7WEN Emit compilation errors from Fluent source code
  • [6] VQBJBFEX Improve error handling for missing Fluent messages
  • [7] OWXLFLRM Merge `cli_macros` shim into `fluent_embed`
  • [8] 4BMW4JJO Add support for deriving items with generics
  • [9] NO3PDO7P Refactor `fluent_embed` to support structs
  • [10] ROSR4HD5 Parse captured glob as locale
  • [11] 3NMKD6I5 Refactor `Localize` trait to use `std::io::Write`
  • [12] CESJ4CTO Move macro-specific code into `macro_impl` module
  • [*] XGNME3WR Move `Group::derive_enum` to new `crate::parse_macro` module
  • [*] 5FIVUZYF Unify `fluent_embed` macro API as `localize()`

Change contents

  • edit in fluent_embed_derive/src/macro_impl/mod.rs at line 13
    [3.24]
    [3.295]
    pub enum UnsupportedReason {
    #[error("Unions are not supported")]
    Union,
    #[error("Unnamed fields are not supported")]
    UnnamedFields,
    }
    #[derive(Debug, Error)]
    #[error("Unsupported Rust code")]
    pub struct UnsupportedError {
    span: syn::Ident,
    reason: UnsupportedReason,
    }
    #[derive(Debug, Error)]
  • edit in fluent_embed_derive/src/macro_impl/mod.rs at line 32
    [3.64]
    [3.458]
    Unsupported(#[from] UnsupportedError),
  • replacement in fluent_embed_derive/src/macro_impl/mod.rs at line 67
    [3.1071][3.1071:1111]()
    syn::Data::Union(_) => todo!(),
    [3.1071]
    [3.1111]
    syn::Data::Union(_) => {
    return Err(MacroError::Unsupported(UnsupportedError {
    span: derive_input.ident.clone(),
    reason: UnsupportedReason::Union,
    }))
    }
  • replacement in fluent_embed_derive/src/macro_impl/mod.rs at line 80
    [3.1404][3.1404:1444]()
    syn::Data::Union(_) => todo!(),
    [3.1404]
    [3.1444]
    syn::Data::Union(_) => {
    return Err(MacroError::Unsupported(UnsupportedError {
    span: derive_input.ident.clone(),
    reason: UnsupportedReason::Union,
    }))
    }
  • replacement in fluent_embed_derive/src/macro_impl/mod.rs at line 100
    [2.1976][2.1976:2002]()
    _ => todo!(),
    [2.1976]
    [2.2002]
    _ => {
    return Err(MacroError::Unsupported(UnsupportedError {
    span: derive_input.ident.clone(),
    reason: UnsupportedReason::UnnamedFields,
    }))
    }
  • replacement in fluent_embed_derive/src/macro_impl/mod.rs at line 110
    [2.2103][2.2103:2159]()
    .flat_map(|variant| match &variant.fields {
    [2.2103]
    [2.2159]
    .map(|variant| match &variant.fields {
  • replacement in fluent_embed_derive/src/macro_impl/mod.rs at line 112
    [2.2213][2.2213:2282]()
    named_fields.named.iter().map(|field| &field.ty)
    [2.2213]
    [2.2282]
    Ok(named_fields.named.iter().map(|field| &field.ty).collect())
  • replacement in fluent_embed_derive/src/macro_impl/mod.rs at line 114
    [2.2300][2.2300:2330]()
    _ => todo!(),
    [2.2300]
    [2.2330]
    _ => Err(MacroError::Unsupported(UnsupportedError {
    span: variant.ident.clone(),
    reason: UnsupportedReason::UnnamedFields,
    })),
  • edit in fluent_embed_derive/src/macro_impl/mod.rs at line 119
    [2.2345]
    [2.2345]
    .collect::<Result<Vec<Vec<&syn::Type>>, _>>()?
    .into_iter()
    .flatten()
  • replacement in fluent_embed_derive/src/macro_impl/error.rs at line 1
    [3.985][3.65:129]()
    use super::{attribute, fluent, fluent::GroupError, MacroError};
    [3.985]
    [3.1027]
    use super::{
    attribute,
    fluent::{self, GroupError},
    MacroError, UnsupportedError, UnsupportedReason,
    };
  • replacement in fluent_embed_derive/src/macro_impl/error.rs at line 92
    [3.829][3.829:868]()
    help = "{}", matched_locales},
    [3.829]
    [3.868]
    help = "{}", matched_locales;
    },
    }
    }
    fn unsupported(error: UnsupportedError) {
    match error.reason {
    UnsupportedReason::Union => emit_error! { error.span, "unions are not supported";
    help = "Use a `struct` or `enum` instead"
    },
    UnsupportedReason::UnnamedFields => {
    emit_error! { error.span, "only named fields are supported";
    help = "Each field needs a name so it can be referenced by Fluent code";
    note = "There must be at least one named field (unit structs are unsupported!)"
    }
    }
  • edit in fluent_embed_derive/src/macro_impl/error.rs at line 115
    [3.943]
    [3.5206]
    MacroError::Unsupported(error) => unsupported(error),
  • edit in fluent_embed_derive/src/macro_impl/derive.rs at line 8
    [15.64]
    [3.9191]
    use super::{MacroError, UnsupportedError, UnsupportedReason};
  • replacement in fluent_embed_derive/src/macro_impl/derive.rs at line 92
    [3.1098][3.1197:1244]()
    ) -> Result<TokenStream, fluent::GroupError> {
    [3.1098]
    [3.1138]
    ) -> Result<TokenStream, MacroError> {
  • replacement in fluent_embed_derive/src/macro_impl/derive.rs at line 101
    [3.1538][3.1538:1620]()
    syn::Fields::Unnamed(_) => todo!(),
    syn::Fields::Unit => todo!(),
    [3.1538]
    [3.1620]
    _ => {
    return Err(MacroError::Unsupported(UnsupportedError {
    span: ident.clone(),
    reason: UnsupportedReason::UnnamedFields,
    }))
    }
  • replacement in fluent_embed_derive/src/macro_impl/derive.rs at line 109
    [3.1628][3.1245:1298]()
    expr_for_message(&mut group, ident, &references)
    [3.1628]
    [3.1589]
    Ok(expr_for_message(&mut group, ident, &references)?)
  • replacement in fluent_embed_derive/src/macro_impl/derive.rs at line 139
    [3.1695][3.1299:1346]()
    ) -> Result<TokenStream, fluent::GroupError> {
    [3.1695]
    [3.1714]
    ) -> Result<TokenStream, MacroError> {
  • replacement in fluent_embed_derive/src/macro_impl/derive.rs at line 156
    [3.2579][3.2579:2669]()
    syn::Fields::Unnamed(_) => todo!(),
    syn::Fields::Unit => todo!(),
    [3.2579]
    [3.2669]
    _ => {
    return Err(MacroError::Unsupported(UnsupportedError {
    span: enum_variant.ident.clone(),
    reason: UnsupportedReason::UnnamedFields,
    }))
    }
  • replacement in fluent_embed_derive/src/macro_impl/derive.rs at line 169
    [3.1973][3.1973:2063]()
    syn::Fields::Unnamed(_) => todo!(),
    syn::Fields::Unit => todo!(),
    [3.1973]
    [3.2063]
    _ => {
    return Err(MacroError::Unsupported(UnsupportedError {
    span: enum_variant.ident.clone(),
    reason: UnsupportedReason::UnnamedFields,
    }))
    }