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,
190 delimiter: syn::MacroDelimiter::Bracket(Bracket(span)),
191 tokens: quote_spanned!(span => #(#exprs),*).into(),
192 },
193 })
194 }
195}