Skip to main content

json_subscriber/
field_writer.rs

1use crate::cursor::Cursor;
2
3/// A writer passed to closures registered with
4/// [`add_multiple_dynamic_fields`](crate::JsonLayer::add_multiple_dynamic_fields).
5///
6/// Call [`write_field`](FieldWriter::write_field) to add key-value pairs directly to the JSON
7/// output. Keys are `&str` (no allocation required for static strings), and values accept any
8/// type that implements [`serde::Serialize`].
9pub struct FieldWriter<'a> {
10    writer: &'a mut String,
11    prefix_comma: bool,
12    wrote_anything: bool,
13}
14
15impl<'a> FieldWriter<'a> {
16    pub(crate) fn new(writer: &'a mut String, prefix_comma: bool) -> Self {
17        Self {
18            writer,
19            prefix_comma,
20            wrote_anything: false,
21        }
22    }
23
24    pub(crate) fn wrote_anything(&self) -> bool {
25        self.wrote_anything
26    }
27
28    /// Writes a single key-value pair into the JSON output.
29    ///
30    /// The key is serialized as a quoted, escaped JSON string. The value can be any type
31    /// implementing [`serde::Serialize`]: strings, numbers, booleans, `Option<T>`, structs
32    /// with `#[derive(Serialize)]`, etc.
33    ///
34    /// Returns `Err` if serialization fails. On error the writer state is rolled back so the
35    /// output remains valid JSON. Errors from this method are rare and indicate a bug in the
36    /// `Serialize` implementation of the value type.
37    ///
38    /// # Errors
39    ///
40    /// This function errors if serialization of the provided value fails. This means that either
41    /// the implementation of `Serialize` decides to fail, or if the value contains a map with
42    /// non-string keys.
43    pub fn write_field(
44        &mut self,
45        key: &str,
46        value: impl serde::Serialize,
47    ) -> serde_json::Result<()> {
48        let rollback = self.writer.len();
49
50        if self.wrote_anything || self.prefix_comma {
51            self.writer.push(',');
52        }
53
54        if let Err(error) = serde_json::to_writer(&Cursor::new(self.writer), key) {
55            self.writer.truncate(rollback);
56            return Err(error);
57        }
58
59        self.writer.push(':');
60
61        if let Err(error) = serde_json::to_writer(&Cursor::new(self.writer), &value) {
62            self.writer.truncate(rollback);
63            return Err(error);
64        }
65
66        self.wrote_anything = true;
67        Ok(())
68    }
69}