1use std::io::Write;
2use std::fmt::Display;
3
4use crate::trace::*;
5use crate::visitor::Visitor;
6
7pub(crate) trait Emitter {
8 fn meta(&mut self, x: u32);
9 fn item(&mut self, s: impl Display);
10 fn text_item(&mut self, s: impl Display);
11 fn opener(&mut self, s: impl Display);
12 fn closer(&mut self);
13 fn maybe_break(&mut self) {}
14 fn finish(self) -> Vec<u8>;
15}
16
17pub(crate) struct ReprEmitter {
18 buf: std::io::Cursor<Vec<u8>>,
19 sibling: bool,
20}
21
22impl ReprEmitter {
23 pub fn new() -> Self {
24 let buf = std::io::Cursor::new(Vec::new());
25 let sibling = false;
26 ReprEmitter { buf, sibling }
27 }
28
29 fn maybe_comma(&mut self) {
30 if self.sibling { self.comma(); }
31 }
32
33 fn comma(&mut self) {
34 write!(self.buf, " ").unwrap();
35 }
36}
37
38impl Emitter for ReprEmitter {
39 fn meta(&mut self, x: u32) {
40 self.maybe_comma();
41 write!(self.buf, "${}", x);
42 self.sibling = true;
43 }
44
45 fn item(&mut self, s: impl Display) {
46 self.maybe_comma();
47 write!(self.buf, "{}", s);
48 self.sibling = true;
49 }
50
51 fn text_item(&mut self, s: impl Display) {
52 self.maybe_comma();
53 write!(self.buf, "{}", s);
54 self.sibling = true;
55 }
56
57 fn opener(&mut self, s: impl Display) {
58 self.maybe_comma();
59 write!(self.buf, "{}{{", s);
60 self.sibling = true;
61 }
62
63 fn closer(&mut self) {
64 self.maybe_comma();
65 write!(self.buf, "}}");
66 self.sibling = true;
67 }
68
69 fn maybe_break(&mut self) {
70 if self.buf.position() != 0 {
71 write!(self.buf, "\n");
72 self.sibling = false;
73 }
74 }
75
76 fn finish(self) -> Vec<u8> {
77 self.buf.into_inner()
78 }
79}
80
81pub(crate) struct JsonEmitter {
82 buf: std::io::Cursor<Vec<u8>>,
83 sibling: bool,
84 scalar_context: bool,
85}
86
87impl JsonEmitter {
88 pub fn new() -> Self {
89 let mut buf = std::io::Cursor::new(Vec::new());
90 write!(buf, "[");
91 let sibling = false;
92 JsonEmitter { buf, sibling, scalar_context: false }
93 }
94
95 pub fn new_scalar() -> Self {
96 let buf = std::io::Cursor::new(Vec::new());
97 let sibling = false;
98 JsonEmitter { buf, sibling, scalar_context: true }
99 }
100
101 fn maybe_comma(&mut self) {
102 if self.sibling { self.comma(); }
103 }
104
105 fn comma(&mut self) {
106 write!(self.buf, ",").unwrap();
107 }
108}
109
110impl Emitter for JsonEmitter {
111 fn finish(mut self) -> Vec<u8> {
112 if !self.scalar_context {
113 write!(self.buf, "]");
114 }
115 self.buf.into_inner()
116 }
117
118 fn meta(&mut self, x: u32) {
119 self.maybe_comma();
120 write!(self.buf, "\"${}\"", x);
121 self.sibling = true;
122 }
123
124 fn item(&mut self, s: impl Display) {
125 self.maybe_comma();
126 write!(self.buf, "{}", s);
127 self.sibling = true;
128 }
129
130 fn text_item(&mut self, s: impl Display) {
131 self.maybe_comma();
132 write!(self.buf, "\"{}\"", s);
133 self.sibling = true;
134 }
135
136 fn opener(&mut self, s: impl Display) {
137 self.maybe_comma();
138 write!(self.buf, "[\"{}\"", s);
139 self.sibling = true;
140 }
141
142 fn closer(&mut self) {
143 write!(self.buf, "]");
144 self.sibling = true;
145 }
146}
147
148pub(crate) struct ReprGenerator<E> {
151 emitter: E,
152 trace: ReTracer,
153}
154
155impl<E: Emitter> ReprGenerator<E> {
156 pub fn new(old: Trace, emitter: E) -> Self {
157 let trace = ReTracer::new(old);
158 ReprGenerator { emitter, trace }
159 }
160
161 pub fn finish(self) -> Vec<u8> {
162 self.emitter.finish()
163 }
164}
165
166impl<E: Emitter> Visitor<'_> for ReprGenerator<E> {
167 fn open_expr(&mut self, x: &syn::Expr) -> Result<(), ()> {
168 if let Err(()) = self.trace.open_subtree() {
169 let x = u32::from(self.trace.consume_meta());
170 self.emitter.meta(x);
171 return Err(());
172 }
173 self.emitter.opener(crate::names::expr_discrim(x));
174 Ok(())
175 }
176 fn open_ident(&mut self, x: &syn::Ident) -> Result<(), ()> {
177 if let Err(()) = self.trace.open_subtree() {
178 let x = u32::from(self.trace.consume_meta());
179 self.emitter.meta(x);
180 return Err(());
181 }
182 self.emitter.text_item(x);
183 Ok(())
184 }
185 fn open_stmt(&mut self, x: &syn::Stmt) {
186 self.open_subtree();
187 self.emitter.maybe_break();
188 self.emitter.opener(crate::names::stmt_discrim(x));
189 }
190 fn open_pat(&mut self, x: &syn::Pat) {
191 self.open_subtree();
192 self.emitter.opener(crate::names::pat_discrim(x));
193 }
194 fn open_lit_int(&mut self, x: &syn::LitInt) {
195 self.open_datum();
196 self.emitter.item(x.value());
197 }
198
199 fn close_expr(&mut self, _: &syn::Expr) {
200 self.close_subtree();
201 self.emitter.closer();
202 }
203 fn close_stmt(&mut self, _: &syn::Stmt) {
204 self.close_subtree();
205 self.emitter.closer();
206 }
207 fn close_pat(&mut self, _: &syn::Pat) {
208 self.close_subtree();
209 self.emitter.closer();
210 }
211
212 fn open_subtree(&mut self) { self.trace.open_subtree().unwrap(); }
213 fn close_subtree(&mut self) { self.trace.close_subtree().unwrap(); }
214 fn open_datum(&mut self) { self.trace.open_datum(); }
215 fn close_datum(&mut self) { self.trace.close_datum(); }
216 fn push_byte(&mut self, x: u8) { self.trace.push_byte(x); }
217 fn extend_bytes(&mut self, x: &[u8]) { self.trace.extend_bytes(x); }
218}
219
220pub(crate) struct PlainAstRepr<E> {
222 emitter: E,
223}
224
225impl<E: Emitter> PlainAstRepr<E> {
226 pub fn new(emitter: E) -> Self {
227 PlainAstRepr { emitter }
228 }
229
230 pub fn finish(self) -> Vec<u8> {
231 self.emitter.finish()
232 }
233}
234
235
236impl<E: Emitter> Visitor<'_> for PlainAstRepr<E> {
237 fn open_expr(&mut self, x: &syn::Expr) -> Result<(), ()> {
238 self.emitter.opener(crate::names::expr_discrim(x));
239 Ok(())
240 }
241 fn open_ident(&mut self, x: &syn::Ident) -> Result<(), ()> {
242 self.emitter.text_item(x);
243 Ok(())
244 }
245 fn open_stmt(&mut self, x: &syn::Stmt) {
246 self.emitter.maybe_break();
247 self.emitter.opener(crate::names::stmt_discrim(x));
248 }
249 fn open_pat(&mut self, x: &syn::Pat) {
250 self.emitter.opener(crate::names::pat_discrim(x));
251 }
252 fn open_lit_int(&mut self, x: &syn::LitInt) {
253 self.emitter.item(x.value());
254 }
255
256 fn close_expr(&mut self, _: &syn::Expr) {
257 self.emitter.closer();
258 }
259 fn close_stmt(&mut self, _: &syn::Stmt) {
260 self.emitter.closer();
261 }
262 fn close_pat(&mut self, _: &syn::Pat) {
263 self.emitter.closer();
264 }
265
266 fn open_subtree(&mut self) {}
267 fn close_subtree(&mut self) {}
268 fn open_datum(&mut self) {}
269 fn close_datum(&mut self) {}
270 fn push_byte(&mut self, x: u8) {}
271 fn extend_bytes(&mut self, x: &[u8]) {}
272}
273