about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--xtask/Cargo.toml1
-rw-r--r--xtask/src/metrics.rs132
3 files changed, 22 insertions, 118 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 234c314067e..c974022a2da 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1832,6 +1832,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
+name = "write-json"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b3f9a784c809a99e38d2e825907617cb03bd880d5421153bc4548e9317f59d0"
+
+[[package]]
 name = "ws2_32-sys"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1852,4 +1858,5 @@ dependencies = [
  "quote",
  "ungrammar",
  "walkdir",
+ "write-json",
 ]
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 8140da87f9e..72a2ae26b84 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -17,3 +17,4 @@ proc-macro2 = "1.0.8"
 quote = "1.0.2"
 ungrammar = "0.1.0"
 walkdir = "2.3.1"
+write-json =  "0.1.0"
diff --git a/xtask/src/metrics.rs b/xtask/src/metrics.rs
index 9ac3fa51d06..4bade2c7e27 100644
--- a/xtask/src/metrics.rs
+++ b/xtask/src/metrics.rs
@@ -1,7 +1,6 @@
 use std::{
     collections::BTreeMap,
     env,
-    fmt::{self, Write as _},
     io::Write as _,
     path::Path,
     time::{Instant, SystemTime, UNIX_EPOCH},
@@ -127,40 +126,21 @@ impl Metrics {
         self.metrics.insert(name.into(), (value, unit));
     }
 
-    fn json(&self) -> Json {
-        let mut json = Json::default();
-        self.to_json(&mut json);
-        json
+    fn json(&self) -> String {
+        let mut buf = String::new();
+        self.to_json(write_json::object(&mut buf));
+        buf
     }
-    fn to_json(&self, json: &mut Json) {
-        json.begin_object();
-        {
-            json.field("host");
-            self.host.to_json(json);
-
-            json.field("timestamp");
-            let timestamp = self.timestamp.duration_since(UNIX_EPOCH).unwrap();
-            json.number(timestamp.as_secs() as f64);
 
-            json.field("revision");
-            json.string(&self.revision);
-
-            json.field("metrics");
-            json.begin_object();
-            {
-                for (k, (value, unit)) in &self.metrics {
-                    json.field(k);
-                    json.begin_array();
-                    {
-                        json.number(*value as f64);
-                        json.string(unit);
-                    }
-                    json.end_array();
-                }
-            }
-            json.end_object()
+    fn to_json(&self, mut obj: write_json::Object<'_>) {
+        self.host.to_json(obj.object("host"));
+        let timestamp = self.timestamp.duration_since(UNIX_EPOCH).unwrap();
+        obj.number("timestamp", timestamp.as_secs() as f64);
+        obj.string("revision", &self.revision);
+        let mut metrics = obj.object("metrics");
+        for (k, (value, unit)) in &self.metrics {
+            metrics.array(k).number(*value as f64).string(unit);
         }
-        json.end_object();
     }
 }
 
@@ -189,91 +169,7 @@ impl Host {
             Ok(line[field.len()..].trim().to_string())
         }
     }
-    fn to_json(&self, json: &mut Json) {
-        json.begin_object();
-        {
-            json.field("os");
-            json.string(&self.os);
-
-            json.field("cpu");
-            json.string(&self.cpu);
-
-            json.field("mem");
-            json.string(&self.mem);
-        }
-        json.end_object();
-    }
-}
-
-struct State {
-    obj: bool,
-    first: bool,
-}
-
-#[derive(Default)]
-struct Json {
-    stack: Vec<State>,
-    buf: String,
-}
-
-impl Json {
-    fn begin_object(&mut self) {
-        self.stack.push(State { obj: true, first: true });
-        self.buf.push('{');
-    }
-    fn end_object(&mut self) {
-        self.stack.pop();
-        self.buf.push('}')
-    }
-    fn begin_array(&mut self) {
-        self.stack.push(State { obj: false, first: true });
-        self.buf.push('[');
-    }
-    fn end_array(&mut self) {
-        self.stack.pop();
-        self.buf.push(']')
-    }
-    fn field(&mut self, name: &str) {
-        self.object_comma();
-        self.string_token(name);
-        self.buf.push(':');
-    }
-    fn string(&mut self, value: &str) {
-        self.array_comma();
-        self.string_token(value);
-    }
-    fn string_token(&mut self, value: &str) {
-        self.buf.push('"');
-        self.buf.extend(value.escape_default());
-        self.buf.push('"');
-    }
-    fn number(&mut self, value: f64) {
-        self.array_comma();
-        write!(self.buf, "{}", value).unwrap();
-    }
-
-    fn array_comma(&mut self) {
-        let state = self.stack.last_mut().unwrap();
-        if state.obj {
-            return;
-        }
-        if !state.first {
-            self.buf.push(',');
-        }
-        state.first = false;
-    }
-
-    fn object_comma(&mut self) {
-        let state = self.stack.last_mut().unwrap();
-        if !state.first {
-            self.buf.push(',');
-        }
-        state.first = false;
-    }
-}
-
-impl fmt::Display for Json {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.buf)
+    fn to_json(&self, mut obj: write_json::Object<'_>) {
+        obj.string("os", &self.os).string("cpu", &self.cpu).string("mem", &self.mem);
     }
 }