1 | use proc_macro2::{Span, TokenStream}; |
2 | use quote::{quote, quote_spanned, ToTokens, TokenStreamExt}; |
3 | use syn::{spanned::Spanned, Ident, Path}; |
4 | |
5 | /// This will be in scope during struct initialization after option parsing. |
6 | const DEFAULT_STRUCT_NAME: &str = "__default" ; |
7 | |
8 | /// The fallback value for a field or container. |
9 | #[derive (Debug, Clone)] |
10 | pub enum DefaultExpression<'a> { |
11 | /// Only valid on fields, `Inherit` indicates that the value should be taken from a pre-constructed |
12 | /// fallback object. The value in the variant is the ident of the field. |
13 | Inherit(&'a Ident), |
14 | Explicit(&'a Path), |
15 | Trait { |
16 | span: Span, |
17 | }, |
18 | } |
19 | |
20 | impl<'a> DefaultExpression<'a> { |
21 | pub fn as_declaration(&'a self) -> DefaultDeclaration<'a> { |
22 | DefaultDeclaration(self) |
23 | } |
24 | } |
25 | |
26 | impl<'a> ToTokens for DefaultExpression<'a> { |
27 | fn to_tokens(&self, tokens: &mut TokenStream) { |
28 | tokens.append_all(iter:match *self { |
29 | DefaultExpression::Inherit(ident: &Ident) => { |
30 | let dsn: Ident = Ident::new(DEFAULT_STRUCT_NAME, ::proc_macro2::Span::call_site()); |
31 | quote!(#dsn.#ident) |
32 | } |
33 | DefaultExpression::Explicit(path: &Path) => { |
34 | // Use quote_spanned to properly set the span of the parentheses |
35 | quote_spanned!(path.span()=>#path()) |
36 | } |
37 | DefaultExpression::Trait { span: Span } => { |
38 | quote_spanned!(span=> ::darling::export::Default::default()) |
39 | } |
40 | }); |
41 | } |
42 | } |
43 | |
44 | /// Used only by containers, this wrapper type generates code to declare the fallback instance. |
45 | pub struct DefaultDeclaration<'a>(&'a DefaultExpression<'a>); |
46 | |
47 | impl<'a> ToTokens for DefaultDeclaration<'a> { |
48 | fn to_tokens(&self, tokens: &mut TokenStream) { |
49 | let name: Ident = Ident::new(DEFAULT_STRUCT_NAME, ::proc_macro2::Span::call_site()); |
50 | let expr: &DefaultExpression<'_> = self.0; |
51 | tokens.append_all(iter:quote!(let #name: Self = #expr;)); |
52 | } |
53 | } |
54 | |