Commit Diff


commit - 81da6bfb1e2a88e73c336de60e3f677eb4ee6153
commit + 3ef8fec0d3e020a8237a883745f82891e4e4bcb8
blob - be04c37f1932a88c537fad7aa5a15fe78c803ced
blob + 6bd4e49e4e2d2bc6e01c39b781b5bcb5ae56764c
--- src/metrics.rs
+++ src/metrics.rs
@@ -4,30 +4,25 @@ use std::{
     iter::FusedIterator,
 };
 
-pub fn escape(s: &str) -> Cow<str> {
-    fn truncate_and_push_str(cow: &mut Cow<str>, new_len: usize, string: &str) {
-        match cow {
-            Cow::Borrowed(_) => {
-                let o = cow.to_mut();
-                o.truncate(new_len);
-                o.push_str(string);
+pub fn escape(string: &str) -> Cow<str> {
+    let escapes = string
+        .chars()
+        .filter(|c| *c == '\n' || *c == '"' || *c == '\\')
+        .count();
+    if escapes == 0 {
+        Cow::Borrowed(string)
+    } else {
+        let mut escaped = String::with_capacity(string.len() + escapes);
+        for c in string.chars() {
+            match c {
+                '\n' => escaped.push_str("\\n"),
+                '"' => escaped.push_str("\\\""),
+                '\\' => escaped.push_str("\\\\"),
+                _ => escaped.push(c),
             }
-            Cow::Owned(ref mut o) => o.push_str(string),
         }
+        Cow::Owned(escaped)
     }
-    let mut escaped = Cow::Borrowed(s);
-    for (i, c) in s.char_indices() {
-        match c {
-            '\n' => truncate_and_push_str(&mut escaped, i, "\\n"),
-            '"' => truncate_and_push_str(&mut escaped, i, "\\\""),
-            '\\' => truncate_and_push_str(&mut escaped, i, "\\\\"),
-            _ => match escaped {
-                Cow::Borrowed(_) => (),
-                Cow::Owned(ref mut o) => o.push(c),
-            },
-        }
-    }
-    escaped
 }
 
 use crate::s6::{ServiceDir, Status};