deser_core/ser/stream.rs
1use crate::error::Error;
2use crate::ser::{SerializeDriver, Serializer};
3
4/// A [`Serializer`] that writes bytes which can be taken while values are
5/// serialized.
6///
7/// This is implemented by the serializers of the data formats (for
8/// instance `deser_json::Serializer`). They hold the state of a stream of
9/// values (for instance how many values were written, or the names of the
10/// columns of a CSV file) and write everything that separates the values
11/// of a stream, like the line breaks of JSON Lines or the markers between
12/// YAML documents.
13///
14/// The bytes serialized so far are in [`output`](Self::output), whoever
15/// writes them to a stream clears them with
16/// [`clear_output`](Self::clear_output) afterwards. This makes stream
17/// serializers usable without IO (sans-io): the writers of `deser::io`
18/// and of other IO adapters (like `deser-tokio`) only move the output to
19/// their stream.
20///
21/// ```
22/// use deser::ser::{SerializeDriver, Serializer, StreamSerializer};
23/// use deser::{Atom, Error, Event};
24///
25/// /// A format with a number per line.
26/// #[derive(Default)]
27/// struct Lines(Vec<u8>);
28///
29/// impl Serializer for Lines {
30/// fn drive(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
31/// driver.drive(|event, _| {
32/// if let Event::Atom(Atom::U64(value)) = event {
33/// self.0.extend_from_slice(format!("{value}\n").as_bytes());
34/// }
35/// Ok(())
36/// })
37/// }
38/// }
39///
40/// impl StreamSerializer for Lines {
41/// fn output(&self) -> &[u8] {
42/// &self.0
43/// }
44///
45/// fn clear_output(&mut self) {
46/// self.0.clear();
47/// }
48/// }
49///
50/// let mut lines = Lines::default();
51/// lines.serialize(&1u64).unwrap();
52/// lines.serialize(&2u64).unwrap();
53/// // the output would be written to a stream here
54/// assert_eq!(lines.output(), b"1\n2\n");
55/// lines.clear_output();
56/// ```
57///
58/// # Serializing in Parts
59///
60/// Formats which can write the output of a value before the value is
61/// complete additionally implement [`drive_partial`](Self::drive_partial).
62/// Writers use it to write large values in parts, so the memory used does
63/// not depend on the size of the values. While a value is written in
64/// parts, [`in_progress`](Self::in_progress) is `true`.
65pub trait StreamSerializer: Serializer {
66 /// Returns the bytes serialized so far which were not cleared yet.
67 ///
68 /// The output only holds final bytes: output that can still change
69 /// (for instance the header of a container whose length is not known
70 /// yet) is kept by the serializer until it's final.
71 fn output(&self) -> &[u8];
72
73 /// Discards the bytes returned by [`output`](Self::output), for
74 /// instance because they were written.
75 fn clear_output(&mut self);
76
77 /// Returns `true` if the serializer implements
78 /// [`drive_partial`](Self::drive_partial).
79 ///
80 /// This can depend on the configuration.
81 fn supports_partial(&self) -> bool {
82 false
83 }
84
85 /// Serializes a value, or a part of it, and appends its bytes to the
86 /// output.
87 ///
88 /// Returns `true` once the value is complete. This works like
89 /// [`drive`](Serializer::drive) but the serializer can stop once the
90 /// output holds at least `limit` bytes (it can hold more) and return
91 /// `false`. The caller then takes the output, clears it and calls
92 /// again with the same driver until the value is complete. In between
93 /// [`in_progress`](Self::in_progress) is `true` and no other value can
94 /// be serialized. With a limit of `usize::MAX` the value is always
95 /// completed in a single call, which allows serializers to use faster
96 /// paths (see [`SerializeDriver::drive_until`]).
97 ///
98 /// If this fails in the first call for a value, the output and the
99 /// state are as before the call (like with [`drive`](Serializer::drive))
100 /// and the next value can be serialized. If it fails after a part was
101 /// returned, the bytes of the part cannot be taken back: the value
102 /// stays in progress and the stream cannot continue.
103 ///
104 /// The provided implementation serializes the whole value with
105 /// [`drive`](Serializer::drive).
106 fn drive_partial(
107 &mut self,
108 driver: &mut SerializeDriver<'_>,
109 limit: usize,
110 ) -> Result<bool, Error> {
111 let _ = limit;
112 self.drive(driver)?;
113 Ok(true)
114 }
115
116 /// Returns `true` if a value is partially serialized.
117 ///
118 /// This is the case after [`drive_partial`](Self::drive_partial)
119 /// returned `false` until it returns `true`.
120 /// If the value is abandoned (because it failed, or because the caller
121 /// gave up on it, for instance when a write failed), this stays `true`:
122 /// the output of the stream holds an incomplete value, so the stream
123 /// cannot continue. Serializing another value fails with
124 /// [`Error::in_progress`].
125 fn in_progress(&self) -> bool {
126 false
127 }
128}
129
130impl<S: StreamSerializer + ?Sized> StreamSerializer for &mut S {
131 fn output(&self) -> &[u8] {
132 (**self).output()
133 }
134
135 fn clear_output(&mut self) {
136 (**self).clear_output()
137 }
138
139 fn supports_partial(&self) -> bool {
140 (**self).supports_partial()
141 }
142
143 fn drive_partial(
144 &mut self,
145 driver: &mut SerializeDriver<'_>,
146 limit: usize,
147 ) -> Result<bool, Error> {
148 (**self).drive_partial(driver, limit)
149 }
150
151 fn in_progress(&self) -> bool {
152 (**self).in_progress()
153 }
154}