darling_core/options/
forwarded_field.rs1use quote::{quote, ToTokens, TokenStreamExt};
2use syn::{Ident, Path};
3
4use crate::{Error, FromField, FromMeta};
5
6use super::ParseAttribute;
7
8#[derive(Debug, Clone)]
10pub struct ForwardedField {
11 pub ident: Ident,
13 pub with: Option<Path>,
16}
17
18impl ForwardedField {
19 pub fn as_initializer(&self) -> Initializer<'_> {
21 Initializer(self)
22 }
23}
24
25impl FromField for ForwardedField {
26 fn from_field(field: &syn::Field) -> crate::Result<Self> {
27 let result = Self {
28 ident: field.ident.clone().ok_or_else(|| {
29 Error::custom("forwarded field must be named field").with_span(field)
30 })?,
31 with: None,
32 };
33
34 result.parse_attributes(&field.attrs)
35 }
36}
37
38impl ParseAttribute for ForwardedField {
39 fn parse_nested(&mut self, mi: &syn::Meta) -> crate::Result<()> {
40 if mi.path().is_ident("with") {
41 if self.with.is_some() {
42 return Err(Error::duplicate_field_path(mi.path()).with_span(mi));
43 }
44
45 self.with = FromMeta::from_meta(mi)?;
46 Ok(())
47 } else {
48 Err(Error::unknown_field_path_with_alts(mi.path(), &["with"]).with_span(mi))
49 }
50 }
51}
52
53pub struct Initializer<'a>(&'a ForwardedField);
59
60impl ToTokens for Initializer<'_> {
61 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
62 let ident = &self.0.ident;
63 tokens.append_all(quote!(#ident: #ident.expect("Errors were already checked"),));
64 }
65}