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}