|
1 | 1 | use std::{ |
2 | 2 | collections::BTreeMap, |
3 | 3 | env, |
4 | | - fmt::{self, Write as _}, |
5 | 4 | io::Write as _, |
6 | 5 | path::Path, |
7 | 6 | time::{Instant, SystemTime, UNIX_EPOCH}, |
@@ -127,40 +126,21 @@ impl Metrics { |
127 | 126 | self.metrics.insert(name.into(), (value, unit)); |
128 | 127 | } |
129 | 128 |
|
130 | | - fn json(&self) -> Json { |
131 | | - let mut json = Json::default(); |
132 | | - self.to_json(&mut json); |
133 | | - json |
| 129 | + fn json(&self) -> String { |
| 130 | + let mut buf = String::new(); |
| 131 | + self.to_json(write_json::object(&mut buf)); |
| 132 | + buf |
134 | 133 | } |
135 | | - fn to_json(&self, json: &mut Json) { |
136 | | - json.begin_object(); |
137 | | - { |
138 | | - json.field("host"); |
139 | | - self.host.to_json(json); |
140 | | - |
141 | | - json.field("timestamp"); |
142 | | - let timestamp = self.timestamp.duration_since(UNIX_EPOCH).unwrap(); |
143 | | - json.number(timestamp.as_secs() as f64); |
144 | 134 |
|
145 | | - json.field("revision"); |
146 | | - json.string(&self.revision); |
147 | | - |
148 | | - json.field("metrics"); |
149 | | - json.begin_object(); |
150 | | - { |
151 | | - for (k, (value, unit)) in &self.metrics { |
152 | | - json.field(k); |
153 | | - json.begin_array(); |
154 | | - { |
155 | | - json.number(*value as f64); |
156 | | - json.string(unit); |
157 | | - } |
158 | | - json.end_array(); |
159 | | - } |
160 | | - } |
161 | | - json.end_object() |
| 135 | + fn to_json(&self, mut obj: write_json::Object<'_>) { |
| 136 | + self.host.to_json(obj.object("host")); |
| 137 | + let timestamp = self.timestamp.duration_since(UNIX_EPOCH).unwrap(); |
| 138 | + obj.number("timestamp", timestamp.as_secs() as f64); |
| 139 | + obj.string("revision", &self.revision); |
| 140 | + let mut metrics = obj.object("metrics"); |
| 141 | + for (k, (value, unit)) in &self.metrics { |
| 142 | + metrics.array(k).number(*value as f64).string(unit); |
162 | 143 | } |
163 | | - json.end_object(); |
164 | 144 | } |
165 | 145 | } |
166 | 146 |
|
@@ -189,91 +169,7 @@ impl Host { |
189 | 169 | Ok(line[field.len()..].trim().to_string()) |
190 | 170 | } |
191 | 171 | } |
192 | | - fn to_json(&self, json: &mut Json) { |
193 | | - json.begin_object(); |
194 | | - { |
195 | | - json.field("os"); |
196 | | - json.string(&self.os); |
197 | | - |
198 | | - json.field("cpu"); |
199 | | - json.string(&self.cpu); |
200 | | - |
201 | | - json.field("mem"); |
202 | | - json.string(&self.mem); |
203 | | - } |
204 | | - json.end_object(); |
205 | | - } |
206 | | -} |
207 | | - |
208 | | -struct State { |
209 | | - obj: bool, |
210 | | - first: bool, |
211 | | -} |
212 | | - |
213 | | -#[derive(Default)] |
214 | | -struct Json { |
215 | | - stack: Vec<State>, |
216 | | - buf: String, |
217 | | -} |
218 | | - |
219 | | -impl Json { |
220 | | - fn begin_object(&mut self) { |
221 | | - self.stack.push(State { obj: true, first: true }); |
222 | | - self.buf.push('{'); |
223 | | - } |
224 | | - fn end_object(&mut self) { |
225 | | - self.stack.pop(); |
226 | | - self.buf.push('}') |
227 | | - } |
228 | | - fn begin_array(&mut self) { |
229 | | - self.stack.push(State { obj: false, first: true }); |
230 | | - self.buf.push('['); |
231 | | - } |
232 | | - fn end_array(&mut self) { |
233 | | - self.stack.pop(); |
234 | | - self.buf.push(']') |
235 | | - } |
236 | | - fn field(&mut self, name: &str) { |
237 | | - self.object_comma(); |
238 | | - self.string_token(name); |
239 | | - self.buf.push(':'); |
240 | | - } |
241 | | - fn string(&mut self, value: &str) { |
242 | | - self.array_comma(); |
243 | | - self.string_token(value); |
244 | | - } |
245 | | - fn string_token(&mut self, value: &str) { |
246 | | - self.buf.push('"'); |
247 | | - self.buf.extend(value.escape_default()); |
248 | | - self.buf.push('"'); |
249 | | - } |
250 | | - fn number(&mut self, value: f64) { |
251 | | - self.array_comma(); |
252 | | - write!(self.buf, "{}", value).unwrap(); |
253 | | - } |
254 | | - |
255 | | - fn array_comma(&mut self) { |
256 | | - let state = self.stack.last_mut().unwrap(); |
257 | | - if state.obj { |
258 | | - return; |
259 | | - } |
260 | | - if !state.first { |
261 | | - self.buf.push(','); |
262 | | - } |
263 | | - state.first = false; |
264 | | - } |
265 | | - |
266 | | - fn object_comma(&mut self) { |
267 | | - let state = self.stack.last_mut().unwrap(); |
268 | | - if !state.first { |
269 | | - self.buf.push(','); |
270 | | - } |
271 | | - state.first = false; |
272 | | - } |
273 | | -} |
274 | | - |
275 | | -impl fmt::Display for Json { |
276 | | - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
277 | | - write!(f, "{}", self.buf) |
| 172 | + fn to_json(&self, mut obj: write_json::Object<'_>) { |
| 173 | + obj.string("os", &self.os).string("cpu", &self.cpu).string("mem", &self.mem); |
278 | 174 | } |
279 | 175 | } |
0 commit comments