darling_core/options/
outer_from.rs1use syn::spanned::Spanned;
2use syn::{Field, Ident, Meta};
3
4use crate::codegen::ForwardAttrs;
5use crate::options::{
6 AttrsField, Core, DefaultExpression, ForwardAttrsFilter, ParseAttribute, ParseData,
7};
8use crate::util::PathList;
9use crate::{FromField, FromMeta, Result};
10
11#[derive(Debug, Clone)]
14pub struct OuterFrom {
15 pub ident: Option<Ident>,
17
18 pub attrs: Option<AttrsField>,
20
21 pub container: Core,
22
23 pub attr_names: PathList,
25
26 pub forward_attrs: Option<ForwardAttrsFilter>,
29
30 pub from_ident: bool,
32}
33
34impl OuterFrom {
35 pub fn start(di: &syn::DeriveInput) -> Result<Self> {
36 Ok(OuterFrom {
37 container: Core::start(di)?,
38 attrs: Default::default(),
39 ident: Default::default(),
40 attr_names: Default::default(),
41 forward_attrs: Default::default(),
42 from_ident: Default::default(),
43 })
44 }
45
46 pub fn as_forward_attrs(&self) -> ForwardAttrs<'_> {
47 ForwardAttrs {
48 field: self.attrs.as_ref(),
49 filter: self.forward_attrs.as_ref(),
50 }
51 }
52}
53
54impl ParseAttribute for OuterFrom {
55 fn parse_nested(&mut self, mi: &Meta) -> Result<()> {
56 let path = mi.path();
57 if path.is_ident("attributes") {
58 self.attr_names = FromMeta::from_meta(mi)?;
59 } else if path.is_ident("forward_attrs") {
60 self.forward_attrs = FromMeta::from_meta(mi)?;
61 } else if path.is_ident("from_ident") {
62 self.container.default = Some(DefaultExpression::Trait {
65 span: path.span(),
68 });
69 self.from_ident = true;
70 } else {
71 return self.container.parse_nested(mi);
72 }
73 Ok(())
74 }
75}
76
77impl ParseData for OuterFrom {
78 fn parse_field(&mut self, field: &Field) -> Result<()> {
79 match field.ident.as_ref().map(|v| v.to_string()).as_deref() {
80 Some("ident") => {
81 self.ident.clone_from(&field.ident);
82 Ok(())
83 }
84 Some("attrs") => {
85 self.attrs = AttrsField::from_field(field).map(Some)?;
86 Ok(())
87 }
88 _ => self.container.parse_field(field),
89 }
90 }
91
92 fn validate_body(&self, errors: &mut crate::error::Accumulator) {
93 self.container.validate_body(errors);
94 }
95}