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 cg.add(&prefixes.get_rust());
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 GetRust for Prefix {
114 fn get_rust(&self) -> String {
115 match self {
116 Self::Deref => "*",
117 Self::Ref => "&",
118 Self::RefMut => "&mut ",
119 Self::Not => "!",
120 Self::New(_) => "",
121 Self::Neg => "-",
122 }
123 .to_string()
124 }
125}
126
127impl GetRust for Vec<Prefix> {
128 fn get_rust(&self) -> String {
129 self.into_iter().map(Prefix::get_rust).collect()
130 }
131}
132
133impl GetRust for Option<&Vec<Prefix>> {
134 fn get_rust(&self) -> String {
135 if let Some(prefixes) = self {
136 prefixes
137 .into_iter()
138 .last()
139 .map(|p| match p {
140 Prefix::New(generics) => format!(
141 "::new{}",
142 generics
143 .clone()
144 .map(|v| format!("::{}", v.get_rust()))
145 .unwrap_or_default(),
146 ),
147 _ => String::new(),
148 })
149 .unwrap_or_default()
150 .to_string()
151 } else {
152 String::new()
153 }
154 }
155}
156
157impl GenRust for Postfix {
158 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
159 match self {
160 Postfix::FieldAccess(field, generics) => cg.add(&format!(
161 ".{}{}",
162 field.get_rust(),
163 generics
164 .iter()
165 .map(|v| format!("::{}", v.get_rust()))
166 .collect::<String>()
167 )),
168
169 Postfix::Call(args) => {
170 cg.add("(");
171
172 for (i, arg) in args.iter().enumerate() {
173 if i > 0 {
174 cg.add(", ");
175 }
176
177 arg.gen_rust(ctx, cg);
178 }
179
180 cg.add(")");
181 }
182
183 Postfix::MacroCall(inner) => {
184 cg.add("!(");
185 cg.add(inner);
186 cg.add(")");
187 }
188
189 Postfix::StructCall(fields) => {
190 cg.add("{");
191
192 for (name, expr) in fields {
193 cg.add(&name.get_rust());
194 cg.add(": ");
195 expr.gen_rust(ctx, cg);
196 cg.add(",");
197 }
198
199 cg.add("}");
200 }
201
202 Postfix::Index(idx) => {
203 cg.add("[");
204 idx.gen_rust(ctx, cg);
205 cg.add("]");
206 }
207
208 Postfix::As(ty) => {
209 cg.add(" as ");
210 cg.add(&ty.get_rust());
211 }
212
213 Postfix::Try => cg.add("?"),
214
215 Postfix::Assign(cmp, expr) => {
216 cg.add(" ");
217 cg.add(cmp);
218 expr.gen_rust(ctx, cg);
219 }
220 Postfix::Increment => cg.add("+=1"),
221 Postfix::Decrement => cg.add("-=1"),
222 }
223 }
224}
225
226impl GetRust for Generics {
227 fn get_rust(&self) -> String {
228 if self.0.len() == 0 {
229 String::new()
230 } else {
231 format!(
232 "<{}>",
233 self.0
234 .iter()
235 .map(Generic::get_rust)
236 .collect::<Vec<_>>()
237 .join(", ")
238 )
239 }
240 }
241}
242
243impl GetRust for Generic {
244 fn get_rust(&self) -> String {
245 match self {
246 Self::Lifetime(name) => format!("'{}", name.get_rust()),
247 Self::Type(ty) => ty.get_rust(),
248 }
249 }
250}