-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathmod.rs
87 lines (69 loc) · 2.48 KB
/
mod.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
mod builder_gen;
mod params;
pub(crate) mod item_impl;
mod item_func;
mod item_struct;
use crate::normalization::{ExpandCfg, ExpansionOutput};
use crate::util;
use crate::util::prelude::*;
use darling::FromMeta;
use quote::quote;
use syn::parse::Parser;
pub(crate) fn generate_from_derive(item: TokenStream2) -> TokenStream2 {
try_generate_from_derive(item).unwrap_or_else(Error::write_errors)
}
fn try_generate_from_derive(item: TokenStream2) -> Result<TokenStream2> {
match syn::parse2(item)? {
syn::Item::Struct(item_struct) => item_struct::generate(item_struct),
_ => bail!(
&proc_macro2::Span::call_site(),
"only `struct` items are supported by the `#[derive(bon::Builder)]` attribute"
),
}
}
pub(crate) fn generate_from_attr(params: TokenStream2, item: TokenStream2) -> TokenStream2 {
try_generate_from_attr(params.clone(), item.clone()).unwrap_or_else(|err| {
[
generate_completion_triggers(params),
crate::error::error_into_token_stream(err, item),
]
.concat()
})
}
fn try_generate_from_attr(params: TokenStream2, item: TokenStream2) -> Result<TokenStream2> {
let item: syn::Item = syn::parse2(item)?;
if let syn::Item::Struct(item_struct) = item {
return Ok(quote! {
use ::bon::private::builder_attribute_on_a_struct as _;
#[derive(::bon::Builder)]
#[builder(#params)]
#item_struct
});
}
let macro_path = syn::parse_quote!(::bon::builder);
let ctx = ExpandCfg {
macro_path,
params,
item,
};
let (params, item) = match ctx.expand_cfg()? {
ExpansionOutput::Expanded { params, item } => (params, item),
ExpansionOutput::Recurse(output) => return Ok(output),
};
let nested_meta = &darling::ast::NestedMeta::parse_meta_list(params.clone())?;
let main_output = match item {
syn::Item::Fn(item_fn) => item_func::generate(FromMeta::from_list(nested_meta)?, item_fn)?,
_ => bail!(
&proc_macro2::Span::call_site(),
"only `fn` items are supported by the `#[bon::builder]` attribute"
),
};
let output = [generate_completion_triggers(params), main_output].concat();
Ok(output)
}
fn generate_completion_triggers(params: TokenStream2) -> TokenStream2 {
let meta = util::ide::parse_comma_separated_meta
.parse2(params)
.unwrap_or_default();
util::ide::generate_completion_triggers(meta)
}