1use mist_parser::ast::*;
2
3use crate::Context;
4
5use crate::{GenRust, GetRust, RustCodegen};
6
7impl GetRust for ExprPath {
8 fn get_rust(&self) -> String {
9 self.0
10 .iter()
11 .map(ExprPathSegment::get_rust)
12 .collect::<Vec<_>>()
13 .join("::")
14 }
15}
16
17impl GetRust for ExprPathSegment {
18 fn get_rust(&self) -> String {
19 format!(
20 "{}{}",
21 self.ident.get_rust(),
22 self.generics
23 .as_ref()
24 .map(|v| format!("::{}", v.get_rust()))
25 .unwrap_or_default()
26 )
27 }
28}
29
30impl GenRust for Literal {
31 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
32 match self {
33 Self::Int(n) => cg.add(&n.to_string()),
34 Self::Float(n) => cg.add(&format!("{n:?}")),
35 Self::Bool(b) => cg.add(&b.to_string()),
36 Self::String(s) => cg.add(&format!("\"{s}\"")),
37
38 Self::Tuple(values) => {
39 cg.add("(");
40
41 for val in values {
42 val.gen_rust(ctx, cg);
43 }
44
45 cg.add(")");
46 }
47
48 Self::Array(values) => {
49 cg.add("[");
50
51 for val in values {
52 val.gen_rust(ctx, cg);
53 }
54
55 cg.add("]");
56 }
57
58 Self::ArrayRepeat(value, repeat) => {
59 cg.add("[");
60 value.gen_rust(ctx, cg);
61 cg.add("; ");
62 repeat.gen_rust(ctx, cg);
63 cg.add("]");
64 }
65 }
66 }
67}
68
69impl GenRust for Expression {
70 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
71 let ensure_semicolon = if ctx.expr_ensure_semicolon {
72 ctx.expr_ensure_semicolon = false;
73
74 true
75 } else {
76 false
77 };
78
79 match self {
80 Expression::Path(path) => cg.add(&path.get_rust()),
81 Expression::Literal(literal) => literal.gen_rust(ctx, cg),
82 Expression::Statement(stmt) => stmt.gen_rust(ctx, cg),
83 Expression::Fix {
84 initial,
85 prefixes,
86 postfixes,
87 } => {
88 prefixes.gen_rust(ctx, cg);
89 initial.gen_rust(ctx, cg);
90 cg.add(&Some(prefixes).get_rust());
91 for postfix in postfixes {
92 postfix.gen_rust(ctx, cg);
93 }
94 }
95 Expression::Binary { lhs, op, rhs } => {
97 lhs.gen_rust(ctx, cg);
98 cg.add(op);
99 rhs.gen_rust(ctx, cg);
100 }
101 }
102
103 if ensure_semicolon {
104 ctx.expr_ensure_semicolon = true;
105
106 if !self.is_block() {
107 cg.add(";");
108 }
109 }
110 }
111}
112
113impl GenRust for Prefix {
114 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
115 match self {
116 Self::Deref => cg.add("*"),
117 Self::Ref => cg.add("&"),
118 Self::RefMut => cg.add("&mut "),
119 Self::Not => cg.add("!"),
120 Self::New(_) => cg.add(""),
121 Self::Neg => cg.add("-"),
122 Self::Closure(ty, args) => {
123 cg.add("|");
124 for (i, arg) in args.iter().enumerate() {
125 if i > 0 {
126 cg.add(", ");
127 }
128
129 arg.gen_rust(ctx, cg);
130 }
131 cg.add("| ");
132
133 if let Some(ty) = ty {
134 cg.add("-> ");
135 cg.add(&ty.get_rust());
136 cg.add(" ");
137 }
138 }
139 }
140 }
141}
142
143impl GenRust for Vec<Prefix> {
144 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
145 for prefix in self {
146 prefix.gen_rust(ctx, cg);
147 }
148 }
149}
150
151impl GetRust for Option<&Vec<Prefix>> {
152 fn get_rust(&self) -> String {
153 if let Some(prefixes) = self {
154 prefixes
155 .into_iter()
156 .last()
157 .map(|p| match p {
158 Prefix::New(generics) => format!(
159 "::new{}",
160 generics
161 .clone()
162 .map(|v| format!("::{}", v.get_rust()))
163 .unwrap_or_default(),
164 ),
165 _ => String::new(),
166 })
167 .unwrap_or_default()
168 .to_string()
169 } else {
170 String::new()
171 }
172 }
173}
174
175impl GenRust for Postfix {
176 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
177 match self {
178 Postfix::FieldAccess(field, generics) => cg.add(&format!(
179 ".{}{}",
180 field.get_rust(),
181 generics
182 .iter()
183 .map(|v| format!("::{}", v.get_rust()))
184 .collect::<String>()
185 )),
186
187 Postfix::Call(args) => {
188 cg.add("(");
189
190 for (i, arg) in args.iter().enumerate() {
191 if i > 0 {
192 cg.add(", ");
193 }
194
195 arg.gen_rust(ctx, cg);
196 }
197
198 cg.add(")");
199 }
200
201 Postfix::MacroCall(inner) => {
202 cg.add("!(");
203 cg.add(inner);
204 cg.add(")");
205 }
206
207 Postfix::StructCall(fields) => {
208 cg.add("{");
209
210 for (name, expr) in fields {
211 cg.add(&name.get_rust());
212 cg.add(": ");
213 expr.gen_rust(ctx, cg);
214 cg.add(",");
215 }
216
217 cg.add("}");
218 }
219
220 Postfix::Index(idx) => {
221 cg.add("[");
222 idx.gen_rust(ctx, cg);
223 cg.add("]");
224 }
225
226 Postfix::As(ty) => {
227 cg.add(" as ");
228 cg.add(&ty.get_rust());
229 }
230
231 Postfix::Try => cg.add("?"),
232
233 Postfix::Assign(cmp, expr) => {
234 cg.add(" ");
235 cg.add(cmp);
236 expr.gen_rust(ctx, cg);
237 }
238 Postfix::Increment => cg.add("+=1"),
239 Postfix::Decrement => cg.add("-=1"),
240 }
241 }
242}
243
244impl GetRust for Generics {
245 fn get_rust(&self) -> String {
246 if self.0.len() == 0 {
247 String::new()
248 } else {
249 format!(
250 "<{}>",
251 self.0
252 .iter()
253 .map(Generic::get_rust)
254 .collect::<Vec<_>>()
255 .join(", ")
256 )
257 }
258 }
259}
260
261impl GetRust for Generic {
262 fn get_rust(&self) -> String {
263 match self {
264 Self::Lifetime(name) => format!("'{}", name.get_rust()),
265 Self::Type(ty) => ty.get_rust(),
266 }
267 }
268}