qlog: add optional pretty-printing for JSON-SEQ streaming

One of the features of JSON-SEQ is that it can support newlines embedded
in records. Prior to this commit, the qlog streamer only supported a
"condensed mode" of writing events on a single JSON line, which can affect
the usability in some circumstances.

This change adds support for discretionary logging of each individual event
using condensed or pretty formats. A new set of "_pretty" suffixed methods
are provided to allow callers to select the format, without breaking
backwards capability. This design also mimics serde's approach.
diff --git a/qlog/src/streamer.rs b/qlog/src/streamer.rs
index 16761b3..27063b8 100644
--- a/qlog/src/streamer.rs
+++ b/qlog/src/streamer.rs
@@ -146,10 +146,34 @@
         self.add_event_with_instant(event, now)
     }
 
+    /// Writes a serializable to a pretty-printed JSON-SEQ record using
+    /// [std::time::Instant::now()].
+    pub fn add_event_now_pretty<E: Serialize + Eventable>(
+        &mut self, event: E,
+    ) -> Result<()> {
+        let now = std::time::Instant::now();
+
+        self.add_event_with_instant_pretty(event, now)
+    }
+
     /// Writes a serializable to a JSON-SEQ record using the provided
     /// [std::time::Instant].
     pub fn add_event_with_instant<E: Serialize + Eventable>(
-        &mut self, mut event: E, now: std::time::Instant,
+        &mut self, event: E, now: std::time::Instant,
+    ) -> Result<()> {
+        self.event_with_instant(event, now, false)
+    }
+
+    /// Writes a serializable to a pretty-printed JSON-SEQ record using the
+    /// provided [std::time::Instant].
+    pub fn add_event_with_instant_pretty<E: Serialize + Eventable>(
+        &mut self, event: E, now: std::time::Instant,
+    ) -> Result<()> {
+        self.event_with_instant(event, now, true)
+    }
+
+    fn event_with_instant<E: Serialize + Eventable>(
+        &mut self, mut event: E, now: std::time::Instant, pretty: bool,
     ) -> Result<()> {
         if self.state != StreamerState::Ready {
             return Err(Error::InvalidState);
@@ -168,7 +192,11 @@
         let rel_time = dur.as_secs_f32() * 1000.0;
         event.set_time(rel_time);
 
-        self.add_event(event)
+        if pretty {
+            self.add_event_pretty(event)
+        } else {
+            self.add_event(event)
+        }
     }
 
     /// Writes an [Event] based on the provided [EventData] to a JSON-SEQ record
@@ -177,6 +205,14 @@
         self.add_event_data_ex_now(event_data, Default::default())
     }
 
+    /// Writes an [Event] based on the provided [EventData] to a pretty-printed
+    /// JSON-SEQ record at time [std::time::Instant::now()].
+    pub fn add_event_data_now_pretty(
+        &mut self, event_data: EventData,
+    ) -> Result<()> {
+        self.add_event_data_ex_now_pretty(event_data, Default::default())
+    }
+
     /// Writes an [Event] based on the provided [EventData] and [ExData] to a
     /// JSON-SEQ record at time [std::time::Instant::now()].
     pub fn add_event_data_ex_now(
@@ -187,6 +223,16 @@
         self.add_event_data_ex_with_instant(event_data, ex_data, now)
     }
 
+    /// Writes an [Event] based on the provided [EventData] and [ExData] to a
+    /// pretty-printed JSON-SEQ record at time [std::time::Instant::now()].
+    pub fn add_event_data_ex_now_pretty(
+        &mut self, event_data: EventData, ex_data: ExData,
+    ) -> Result<()> {
+        let now = std::time::Instant::now();
+
+        self.add_event_data_ex_with_instant_pretty(event_data, ex_data, now)
+    }
+
     /// Writes an [Event] based on the provided [EventData] and
     /// [std::time::Instant] to a JSON-SEQ record.
     pub fn add_event_data_with_instant(
@@ -195,12 +241,40 @@
         self.add_event_data_ex_with_instant(event_data, Default::default(), now)
     }
 
+    /// Writes an [Event] based on the provided [EventData] and
+    /// [std::time::Instant] to a pretty-printed JSON-SEQ record.
+    pub fn add_event_data_with_instant_pretty(
+        &mut self, event_data: EventData, now: std::time::Instant,
+    ) -> Result<()> {
+        self.add_event_data_ex_with_instant_pretty(
+            event_data,
+            Default::default(),
+            now,
+        )
+    }
+
     /// Writes an [Event] based on the provided [EventData], [ExData], and
     /// [std::time::Instant] to a JSON-SEQ record.
     pub fn add_event_data_ex_with_instant(
         &mut self, event_data: EventData, ex_data: ExData,
         now: std::time::Instant,
     ) -> Result<()> {
+        self.event_data_ex_with_instant(event_data, ex_data, now, false)
+    }
+
+    // Writes an [Event] based on the provided [EventData], [ExData], and
+    /// [std::time::Instant] to a pretty-printed JSON-SEQ record.
+    pub fn add_event_data_ex_with_instant_pretty(
+        &mut self, event_data: EventData, ex_data: ExData,
+        now: std::time::Instant,
+    ) -> Result<()> {
+        self.event_data_ex_with_instant(event_data, ex_data, now, true)
+    }
+
+    fn event_data_ex_with_instant(
+        &mut self, event_data: EventData, ex_data: ExData,
+        now: std::time::Instant, pretty: bool,
+    ) -> Result<()> {
         if self.state != StreamerState::Ready {
             return Err(Error::InvalidState);
         }
@@ -219,13 +293,32 @@
         let rel_time = dur.as_secs_f32() * 1000.0;
         let event = Event::with_time_ex(rel_time, event_data, ex_data);
 
-        self.add_event(event)
+        if pretty {
+            self.add_event_pretty(event)
+        } else {
+            self.add_event(event)
+        }
     }
 
     /// Writes a JSON-SEQ-serialized [Event] using the provided [Event].
     pub fn add_event<E: Serialize + Eventable>(
         &mut self, event: E,
     ) -> Result<()> {
+        self.write_event(event, false)
+    }
+
+    /// Writes a pretty-printed JSON-SEQ-serialized [Event] using the provided
+    /// [Event].
+    pub fn add_event_pretty<E: Serialize + Eventable>(
+        &mut self, event: E,
+    ) -> Result<()> {
+        self.write_event(event, true)
+    }
+
+    /// Writes a JSON-SEQ-serialized [Event] using the provided [Event].
+    fn write_event<E: Serialize + Eventable>(
+        &mut self, event: E, pretty: bool,
+    ) -> Result<()> {
         if self.state != StreamerState::Ready {
             return Err(Error::InvalidState);
         }
@@ -235,8 +328,13 @@
         }
 
         self.writer.as_mut().write_all(b"")?;
-        serde_json::to_writer(self.writer.as_mut(), &event)
-            .map_err(|_| Error::Done)?;
+        if pretty {
+            serde_json::to_writer_pretty(self.writer.as_mut(), &event)
+                .map_err(|_| Error::Done)?;
+        } else {
+            serde_json::to_writer(self.writer.as_mut(), &event)
+                .map_err(|_| Error::Done)?;
+        }
         self.writer.as_mut().write_all(b"\n")?;
 
         Ok(())