1use crate::BlockContents;
2use proc_macro2::Span;
3use quote::ToTokens;
4
5/// A `DefaultExpression` can be either explicit or refer to the canonical trait.
6#[derive(Debug, Clone)]
7pub enum DefaultExpression {
8 Explicit(BlockContents),
9 Trait,
10}
11
12impl DefaultExpression {
13 /// Add the crate root path so the default expression can be emitted
14 /// to a `TokenStream`.
15 ///
16 /// This function is needed because the crate root is inherited from the container, so it cannot
17 /// be provided at parse time to [`darling::FromMeta::from_word`] when reading, and [`ToTokens`] does not
18 /// accept any additional parameters, so it annot be provided at emit time.
19 pub fn with_crate_root<'a>(&'a self, crate_root: &'a syn::Path) -> impl 'a + ToTokens {
20 DefaultExpressionWithCrateRoot {
21 crate_root,
22 expr: self,
23 }
24 }
25
26 #[cfg(test)]
27 pub fn explicit<I: Into<BlockContents>>(content: I) -> Self {
28 DefaultExpression::Explicit(content.into())
29 }
30}
31
32impl darling::FromMeta for DefaultExpression {
33 fn from_word() -> darling::Result<Self> {
34 Ok(DefaultExpression::Trait)
35 }
36
37 fn from_value(value: &syn::Lit) -> darling::Result<Self> {
38 Ok(Self::Explicit(BlockContents::from_value(value)?))
39 }
40}
41
42impl syn::spanned::Spanned for DefaultExpression {
43 fn span(&self) -> Span {
44 match self {
45 DefaultExpression::Explicit(block: &BlockContents) => block.span(),
46 DefaultExpression::Trait => Span::call_site(),
47 }
48 }
49}
50
51/// Wrapper for `DefaultExpression`
52struct DefaultExpressionWithCrateRoot<'a> {
53 crate_root: &'a syn::Path,
54 expr: &'a DefaultExpression,
55}
56
57impl<'a> ToTokens for DefaultExpressionWithCrateRoot<'a> {
58 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
59 let crate_root: &Path = self.crate_root;
60 match self.expr {
61 DefaultExpression::Explicit(ref block: &BlockContents) => block.to_tokens(tokens),
62 DefaultExpression::Trait => quoteTokenStream!(
63 #crate_root::export::core::default::Default::default()
64 )
65 .to_tokens(tokens),
66 }
67 }
68}
69