derive_builder_core/
default_expression.rsuse crate::BlockContents;
use proc_macro2::Span;
use quote::ToTokens;
#[derive(Debug, Clone)]
pub enum DefaultExpression {
Explicit(BlockContents),
Trait,
}
impl DefaultExpression {
pub fn with_crate_root<'a>(&'a self, crate_root: &'a syn::Path) -> impl 'a + ToTokens {
DefaultExpressionWithCrateRoot {
crate_root,
expr: self,
}
}
pub fn span(&self) -> Span {
match self {
DefaultExpression::Explicit(block) => block.span(),
DefaultExpression::Trait => Span::call_site(),
}
}
#[cfg(test)]
pub fn explicit<I: Into<BlockContents>>(content: I) -> Self {
DefaultExpression::Explicit(content.into())
}
}
impl darling::FromMeta for DefaultExpression {
fn from_word() -> darling::Result<Self> {
Ok(DefaultExpression::Trait)
}
fn from_expr(expr: &syn::Expr) -> darling::Result<Self> {
if let syn::Expr::Lit(el) = expr {
if let syn::Lit::Str(_) = el.lit {
return Self::from_value(&el.lit);
}
}
Ok(Self::Explicit(expr.clone().into()))
}
fn from_value(value: &syn::Lit) -> darling::Result<Self> {
Ok(Self::Explicit(BlockContents::from_value(value)?))
}
}
struct DefaultExpressionWithCrateRoot<'a> {
crate_root: &'a syn::Path,
expr: &'a DefaultExpression,
}
impl<'a> ToTokens for DefaultExpressionWithCrateRoot<'a> {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let crate_root = self.crate_root;
match self.expr {
DefaultExpression::Explicit(ref block) => block.to_tokens(tokens),
DefaultExpression::Trait => quote!(
#crate_root::export::core::default::Default::default()
)
.to_tokens(tokens),
}
}
}