syn_prelude/
to_expr.rs

1use quote::quote_spanned;
2use syn::{
3    punctuated::Punctuated, spanned::Spanned, token::Bracket, Expr, ExprLit, ExprMacro, ExprPath,
4    Ident, Lit, LitBool, LitByte, LitByteStr, LitChar, LitFloat, LitInt, LitStr, Macro, Path,
5    PathSegment, Token,
6};
7
8pub trait ToExpr {
9    fn to_expr(self) -> Expr;
10}
11
12impl ToExpr for Expr {
13    fn to_expr(self) -> Expr {
14        self
15    }
16}
17
18impl ToExpr for &Expr {
19    fn to_expr(self) -> Expr {
20        self.clone()
21    }
22}
23
24impl ToExpr for LitStr {
25    fn to_expr(self) -> Expr {
26        Expr::Lit(ExprLit {
27            lit: Lit::Str(self),
28            attrs: vec![],
29        })
30    }
31}
32
33impl ToExpr for &LitStr {
34    fn to_expr(self) -> Expr {
35        Expr::Lit(ExprLit {
36            lit: Lit::Str(self.clone()),
37            attrs: vec![],
38        })
39    }
40}
41
42impl ToExpr for LitInt {
43    fn to_expr(self) -> Expr {
44        Expr::Lit(ExprLit {
45            lit: Lit::Int(self),
46            attrs: vec![],
47        })
48    }
49}
50
51impl ToExpr for &LitInt {
52    fn to_expr(self) -> Expr {
53        Expr::Lit(ExprLit {
54            lit: Lit::Int(self.clone()),
55            attrs: vec![],
56        })
57    }
58}
59
60impl ToExpr for LitFloat {
61    fn to_expr(self) -> Expr {
62        Expr::Lit(ExprLit {
63            lit: Lit::Float(self),
64            attrs: vec![],
65        })
66    }
67}
68
69impl ToExpr for &LitFloat {
70    fn to_expr(self) -> Expr {
71        Expr::Lit(ExprLit {
72            lit: Lit::Float(self.clone()),
73            attrs: vec![],
74        })
75    }
76}
77
78impl ToExpr for LitBool {
79    fn to_expr(self) -> Expr {
80        Expr::Lit(ExprLit {
81            lit: Lit::Bool(self),
82            attrs: vec![],
83        })
84    }
85}
86
87impl ToExpr for &LitBool {
88    fn to_expr(self) -> Expr {
89        Expr::Lit(ExprLit {
90            lit: Lit::Bool(self.clone()),
91            attrs: vec![],
92        })
93    }
94}
95
96impl ToExpr for LitByte {
97    fn to_expr(self) -> Expr {
98        Expr::Lit(ExprLit {
99            lit: Lit::Byte(self),
100            attrs: vec![],
101        })
102    }
103}
104
105impl ToExpr for &LitByte {
106    fn to_expr(self) -> Expr {
107        Expr::Lit(ExprLit {
108            lit: Lit::Byte(self.clone()),
109            attrs: vec![],
110        })
111    }
112}
113
114impl ToExpr for LitByteStr {
115    fn to_expr(self) -> Expr {
116        Expr::Lit(ExprLit {
117            lit: Lit::ByteStr(self),
118            attrs: vec![],
119        })
120    }
121}
122
123impl ToExpr for &LitByteStr {
124    fn to_expr(self) -> Expr {
125        Expr::Lit(ExprLit {
126            lit: Lit::ByteStr(self.clone()),
127            attrs: vec![],
128        })
129    }
130}
131
132impl ToExpr for LitChar {
133    fn to_expr(self) -> Expr {
134        Expr::Lit(ExprLit {
135            lit: Lit::Char(self),
136            attrs: vec![],
137        })
138    }
139}
140
141impl ToExpr for &LitChar {
142    fn to_expr(self) -> Expr {
143        Expr::Lit(ExprLit {
144            lit: Lit::Char(self.clone()),
145            attrs: vec![],
146        })
147    }
148}
149
150impl ToExpr for Path {
151    fn to_expr(self) -> Expr {
152        Expr::Path(ExprPath {
153            attrs: vec![],
154            qself: None,
155            path: self,
156        })
157    }
158}
159
160impl ToExpr for &Path {
161    fn to_expr(self) -> Expr {
162        Expr::Path(ExprPath {
163            attrs: vec![],
164            qself: None,
165            path: self.clone(),
166        })
167    }
168}
169
170impl<T: ToExpr> ToExpr for Vec<T> {
171    fn to_expr(self) -> Expr {
172        let exprs = self.into_iter().map(|x| x.to_expr()).collect::<Vec<_>>();
173        let span = exprs.first().map(|x| x.span()).unwrap();
174
175        Expr::Macro(ExprMacro {
176            attrs: vec![],
177            mac: Macro {
178                path: Path {
179                    leading_colon: None,
180                    segments: {
181                        let mut segments = Punctuated::new();
182                        segments.push(PathSegment {
183                            ident: Ident::new("vec", span),
184                            arguments: syn::PathArguments::None,
185                        });
186                        segments
187                    },
188                },
189                bang_token: Token![!](span),
190                delimiter: syn::MacroDelimiter::Bracket(Bracket(span)),
191                tokens: quote_spanned!(span => #(#exprs),*).into(),
192            },
193        })
194    }
195}