darling_core/util/
callable.rs1use quote::ToTokens;
2use syn::{Expr, ExprClosure, ExprLit, ExprPath, Lit, Path};
3
4use crate::{Error, FromMeta, Result};
5
6#[derive(Debug, Clone)]
17pub struct Callable {
18 call: Expr,
20}
21
22impl AsRef<Expr> for Callable {
23 fn as_ref(&self) -> &Expr {
24 &self.call
25 }
26}
27
28impl From<Path> for Callable {
29 fn from(path: Path) -> Self {
30 Self::from(ExprPath {
31 attrs: vec![],
32 qself: None,
33 path,
34 })
35 }
36}
37
38impl From<ExprPath> for Callable {
39 fn from(value: ExprPath) -> Self {
40 Self {
41 call: Expr::Path(value),
42 }
43 }
44}
45
46impl From<ExprClosure> for Callable {
47 fn from(value: ExprClosure) -> Self {
48 Self {
49 call: Expr::Closure(value),
50 }
51 }
52}
53
54impl From<Callable> for Expr {
55 fn from(value: Callable) -> Self {
56 value.call
57 }
58}
59
60impl FromMeta for Callable {
61 fn from_expr(expr: &Expr) -> Result<Self> {
62 match expr {
63 Expr::Path(_) | Expr::Closure(_) => Ok(Self { call: expr.clone() }),
64 Expr::Lit(ExprLit {
65 lit: Lit::Str(s), ..
66 }) => syn::parse_str::<Path>(&s.value())
67 .map_err(|e| {
68 Error::custom(format!("`with` must be a path if it's a string: {}", e))
69 .with_span(s)
70 })
71 .map(Self::from),
72 _ => Err(Error::unexpected_expr_type(expr)),
73 }
74 }
75}
76
77impl ToTokens for Callable {
78 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
79 self.call.to_tokens(tokens);
80 }
81}