bon_macros/
bon.rs

1use crate::builder;
2use crate::normalization::{ExpandCfg, Expansion};
3use crate::util::prelude::*;
4use darling::ast::NestedMeta;
5use darling::FromMeta;
6
7pub(crate) fn generate(params: TokenStream, item: TokenStream) -> TokenStream {
8    crate::error::handle_errors(item.clone(), || try_generate(params, item))
9        .unwrap_or_else(std::convert::identity)
10}
11
12pub(crate) fn try_generate(params: TokenStream, item: TokenStream) -> Result<TokenStream> {
13    let item: syn::Item = syn::parse2(item)?;
14
15    let ctx = ExpandCfg {
16        current_macro: format_ident!("bon"),
17        config: params,
18        item,
19    };
20
21    let input = match ctx.expand_cfg()? {
22        Expansion::Expanded(input) => input,
23        Expansion::Recurse(output) => return Ok(output),
24    };
25
26    let params = NestedMeta::parse_meta_list(input.config)?;
27    let params = FromMeta::from_list(&params)?;
28
29    match input.item {
30        syn::Item::Impl(item_impl) => builder::item_impl::generate(params, item_impl),
31        _ => bail!(
32            &input.item,
33            "`#[bon]` attribute is expected to be placed on an `impl` block \
34             but it was placed on other syntax instead"
35        ),
36    }
37}