| 1 | use proc_macro2::Span; | 
| 2 | use syn::{parse_quote, spanned::Spanned}; | 
|---|
| 3 |  | 
|---|
| 4 | use crate::ast::NestedMeta; | 
|---|
| 5 | use crate::error::Accumulator; | 
|---|
| 6 | use crate::{Error, FromMeta, Result}; | 
|---|
| 7 |  | 
|---|
| 8 | mod core; | 
|---|
| 9 | mod forward_attrs; | 
|---|
| 10 | mod from_attributes; | 
|---|
| 11 | mod from_derive; | 
|---|
| 12 | mod from_field; | 
|---|
| 13 | mod from_meta; | 
|---|
| 14 | mod from_type_param; | 
|---|
| 15 | mod from_variant; | 
|---|
| 16 | mod input_field; | 
|---|
| 17 | mod input_variant; | 
|---|
| 18 | mod outer_from; | 
|---|
| 19 | mod shape; | 
|---|
| 20 |  | 
|---|
| 21 | pub use self::core::Core; | 
|---|
| 22 | pub use self::forward_attrs::{AttrsField, ForwardAttrsFilter}; | 
|---|
| 23 | pub use self::from_attributes::FromAttributesOptions; | 
|---|
| 24 | pub use self::from_derive::FdiOptions; | 
|---|
| 25 | pub use self::from_field::FromFieldOptions; | 
|---|
| 26 | pub use self::from_meta::FromMetaOptions; | 
|---|
| 27 | pub use self::from_type_param::FromTypeParamOptions; | 
|---|
| 28 | pub use self::from_variant::FromVariantOptions; | 
|---|
| 29 | pub use self::input_field::InputField; | 
|---|
| 30 | pub use self::input_variant::InputVariant; | 
|---|
| 31 | pub use self::outer_from::OuterFrom; | 
|---|
| 32 | pub use self::shape::{DataShape, DeriveInputShapeSet}; | 
|---|
| 33 |  | 
|---|
| 34 | /// A default/fallback expression encountered in attributes during parsing. | 
|---|
| 35 | #[ derive(Debug, Clone)] | 
|---|
| 36 | pub enum DefaultExpression { | 
|---|
| 37 | /// The value should be taken from the `default` instance of the containing struct. | 
|---|
| 38 | /// This is not valid in container options. | 
|---|
| 39 | Inherit, | 
|---|
| 40 | Explicit(syn::Path), | 
|---|
| 41 | Trait { | 
|---|
| 42 | /// The input span that is responsible for the use of `Default::default`. | 
|---|
| 43 | span: Span, | 
|---|
| 44 | }, | 
|---|
| 45 | } | 
|---|
| 46 |  | 
|---|
| 47 | #[ doc(hidden)] | 
|---|
| 48 | impl FromMeta for DefaultExpression { | 
|---|
| 49 | // Note: This cannot use `from_word` as it needs to capture the span | 
|---|
| 50 | // in the `Meta::Path` case. | 
|---|
| 51 | fn from_meta(item: &syn::Meta) -> Result<Self> { | 
|---|
| 52 | match item { | 
|---|
| 53 | syn::Meta::Path(_) => Ok(DefaultExpression::Trait { span: item.span() }), | 
|---|
| 54 | syn::Meta::List(nm: &MetaList) => Err(Error::unsupported_format( "list").with_span(node:nm)), | 
|---|
| 55 | syn::Meta::NameValue(nv: &MetaNameValue) => Self::from_expr(&nv.value), | 
|---|
| 56 | } | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|
| 59 | fn from_expr(expr: &syn::Expr) -> Result<Self> { | 
|---|
| 60 | syn::Path::from_expr(expr).map(op:DefaultExpression::Explicit) | 
|---|
| 61 | } | 
|---|
| 62 |  | 
|---|
| 63 | fn from_value(value: &syn::Lit) -> Result<Self> { | 
|---|
| 64 | syn::Path::from_value(value).map(op:DefaultExpression::Explicit) | 
|---|
| 65 | } | 
|---|
| 66 | } | 
|---|
| 67 |  | 
|---|
| 68 | /// Middleware for extracting attribute values. Implementers are expected to override | 
|---|
| 69 | /// `parse_nested` so they can apply individual items to themselves, while `parse_attributes` | 
|---|
| 70 | /// is responsible for looping through distinct outer attributes and collecting errors. | 
|---|
| 71 | pub trait ParseAttribute: Sized { | 
|---|
| 72 | fn parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self> { | 
|---|
| 73 | let mut errors: Accumulator = Error::accumulator(); | 
|---|
| 74 | for attr: &Attribute in attrs { | 
|---|
| 75 | if attr.meta.path() == &parse_quote!(darling) { | 
|---|
| 76 | errors.handle(result:parse_attr(attr, &mut self)); | 
|---|
| 77 | } | 
|---|
| 78 | } | 
|---|
| 79 |  | 
|---|
| 80 | errors.finish_with(self) | 
|---|
| 81 | } | 
|---|
| 82 |  | 
|---|
| 83 | /// Read a meta-item, and apply its values to the current instance. | 
|---|
| 84 | fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()>; | 
|---|
| 85 | } | 
|---|
| 86 |  | 
|---|
| 87 | fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()> { | 
|---|
| 88 | let mut errors: Accumulator = Error::accumulator(); | 
|---|
| 89 | match &attr.meta { | 
|---|
| 90 | syn::Meta::List(data: &MetaList) => { | 
|---|
| 91 | for item: NestedMeta in NestedMeta::parse_meta_list(data.tokens.clone())? { | 
|---|
| 92 | if let NestedMeta::Meta(ref mi: &Meta) = item { | 
|---|
| 93 | errors.handle(result:target.parse_nested(mi)); | 
|---|
| 94 | } else { | 
|---|
| 95 | panic!( "Wasn't able to parse: `{:?} `", item); | 
|---|
| 96 | } | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | errors.finish() | 
|---|
| 100 | } | 
|---|
| 101 | item: &Meta => panic!( "Wasn't able to parse: `{:?} `", item), | 
|---|
| 102 | } | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | /// Middleware for extracting values from the body of the derive input. Implementers are | 
|---|
| 106 | /// expected to override `parse_field` or `parse_variant` as appropriate for their use-case, | 
|---|
| 107 | /// while `parse_body` dispatches to the appropriate methods and handles error collection. | 
|---|
| 108 | pub trait ParseData: Sized { | 
|---|
| 109 | fn parse_body(mut self, body: &syn::Data) -> Result<Self> { | 
|---|
| 110 | use syn::{Data, Fields}; | 
|---|
| 111 |  | 
|---|
| 112 | let mut errors = Error::accumulator(); | 
|---|
| 113 |  | 
|---|
| 114 | match *body { | 
|---|
| 115 | Data::Struct(ref data) => match data.fields { | 
|---|
| 116 | Fields::Unit => {} | 
|---|
| 117 | Fields::Named(ref fields) => { | 
|---|
| 118 | for field in &fields.named { | 
|---|
| 119 | errors.handle(self.parse_field(field)); | 
|---|
| 120 | } | 
|---|
| 121 | } | 
|---|
| 122 | Fields::Unnamed(ref fields) => { | 
|---|
| 123 | for field in &fields.unnamed { | 
|---|
| 124 | errors.handle(self.parse_field(field)); | 
|---|
| 125 | } | 
|---|
| 126 | } | 
|---|
| 127 | }, | 
|---|
| 128 | Data::Enum(ref data) => { | 
|---|
| 129 | for variant in &data.variants { | 
|---|
| 130 | errors.handle(self.parse_variant(variant)); | 
|---|
| 131 | } | 
|---|
| 132 | } | 
|---|
| 133 | Data::Union(_) => unreachable!(), | 
|---|
| 134 | }; | 
|---|
| 135 |  | 
|---|
| 136 | self.validate_body(&mut errors); | 
|---|
| 137 |  | 
|---|
| 138 | errors.finish_with(self) | 
|---|
| 139 | } | 
|---|
| 140 |  | 
|---|
| 141 | /// Apply the next found variant to the object, returning an error | 
|---|
| 142 | /// if parsing goes wrong. | 
|---|
| 143 | fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> { | 
|---|
| 144 | Err(Error::unsupported_format( "enum variant").with_span(variant)) | 
|---|
| 145 | } | 
|---|
| 146 |  | 
|---|
| 147 | /// Apply the next found struct field to the object, returning an error | 
|---|
| 148 | /// if parsing goes wrong. | 
|---|
| 149 | fn parse_field(&mut self, field: &syn::Field) -> Result<()> { | 
|---|
| 150 | Err(Error::unsupported_format( "struct field").with_span(field)) | 
|---|
| 151 | } | 
|---|
| 152 |  | 
|---|
| 153 | /// Perform validation checks that require data from more than one field or variant. | 
|---|
| 154 | /// The default implementation does no validations. | 
|---|
| 155 | /// Implementors can override this method as appropriate for their use-case. | 
|---|
| 156 | #[ allow(unused_variables)] | 
|---|
| 157 | fn validate_body(&self, errors: &mut Accumulator) {} | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|