substrate_data/wire/stream.rs
1//! [`Stream`]: a list kept in the binary form: its items written as they
2//! come (no `Vec` of them on the way), cut out whole when the stream is
3//! decoded and read back one at a time, when asked. For the big ones: a
4//! table's rows, a picture's pixels, a log.
5//!
6//! Decoding a stream checks its framing only (its byte length and its item
7//! count against the bytes there are), so it costs a copy, not a pass over
8//! the items. An item is read when it is asked for, and
9//! [`Stream::iter`] yields a `Result` for each: a bad item is an
10//! [`ItemError`](crate::ItemError) naming its index and byte.
11//!
12//! ```
13//! use substrate_data::{Schema, Stream};
14//!
15//! #[derive(Schema)]
16//! struct Sheet {
17//! name: String,
18//! cells: Stream<u16>,
19//! }
20//!
21//! let sheet = Sheet { name: "q3".into(), cells: (0..1000u16).map(|i| i % 3).collect() };
22//! let back: Sheet = substrate_data::read_bytes(&substrate_data::to_bytes(&sheet)).unwrap();
23//! assert_eq!(back.cells.len(), 1000);
24//! let twos = back.cells.iter().filter(|c| matches!(c, Ok(2))).count();
25//! assert_eq!(twos, 333);
26//! // All of them, or the first that cannot be read:
27//! let cells: Vec<u16> = back.cells.iter().collect::<Result<_, _>>().unwrap();
28//! assert_eq!(cells.len(), 1000);
29//! ```
30
31use std::fmt;
32use std::marker::PhantomData;
33
34use super::item_error::ItemError;
35use super::items::Items;
36use super::stream_writer::StreamWriter;
37use crate::binary::{Decoder, Writer};
38use crate::frame::{Packer, Unpacker};
39use crate::model::borrowed::ValueRef;
40use crate::model::value::{Seg, Value};
41use crate::schema::{Reader, Schema, Shape};
42
43/// A list of `T` kept written: its body in the binary form, its strings its own.
44///
45/// A stream that was built here (`collect`, `From<Vec<T>>`, a
46/// [`StreamWriter`]) always reads. A decoded one has had its framing checked
47/// and nothing more, so an item can fail when it is read: see [`Stream::iter`].
48///
49/// Two streams are equal when they have the same count and the same bytes,
50/// not when their items are equal: the same items written by another encoder
51/// (a different but valid spelling of an int, say) are not equal, and a
52/// stream with an unreadable item equals only a copy of itself. Compare
53/// [`Stream::to_vec`] to compare items.
54pub struct Stream<T> {
55 /// The items, written one after another.
56 items: Vec<u8>,
57 len: usize,
58 item: PhantomData<fn() -> T>,
59}
60
61impl<T> Stream<T> {
62 pub(super) fn from_written(items: Vec<u8>, len: usize) -> Self {
63 Stream {
64 items,
65 len,
66 item: PhantomData,
67 }
68 }
69
70 /// How many items it says it has (a decoded stream's are not read yet).
71 #[must_use]
72 pub fn len(&self) -> usize {
73 self.len
74 }
75
76 /// Whether it says it has none.
77 #[must_use]
78 pub fn is_empty(&self) -> bool {
79 self.len == 0
80 }
81
82 /// How many bytes it takes.
83 #[must_use]
84 pub fn bytes_len(&self) -> usize {
85 self.items.len()
86 }
87}
88
89impl<T: Schema> Stream<T> {
90 /// Writes items one by one ([`StreamWriter::push`]).
91 #[must_use]
92 pub fn writer() -> StreamWriter<T> {
93 StreamWriter {
94 w: Writer::body(),
95 len: 0,
96 item: PhantomData,
97 }
98 }
99
100 /// The items, each read as it's asked for.
101 ///
102 /// An item that cannot be read (a newer item type, a corrupt byte) is an
103 /// `Err` naming its index and byte, and the iterator ends there; so does
104 /// a stream with bytes left after its counted items, with an `Err` at
105 /// index [`len`](Stream::len). `iter().collect::<Result<Vec<_>, _>>()`
106 /// reads them all or stops at the first bad one.
107 #[must_use]
108 pub fn iter(&self) -> Items<'_, T> {
109 Items::new(&self.items, self.len)
110 }
111
112 /// Every item, read now: the first that cannot be read is the error.
113 ///
114 /// # Errors
115 ///
116 /// An [`ItemError`] for the first unreadable item.
117 pub fn to_vec(&self) -> Result<Vec<T>, ItemError> {
118 self.iter().collect()
119 }
120
121 /// Reads every item and drops it: whether the whole stream reads.
122 ///
123 /// # Errors
124 ///
125 /// An [`ItemError`] for the first unreadable item.
126 pub fn validate(&self) -> Result<(), ItemError> {
127 self.iter().try_for_each(|item| item.map(drop))
128 }
129}
130
131impl<'a, T: Schema> IntoIterator for &'a Stream<T> {
132 type Item = Result<T, ItemError>;
133 type IntoIter = Items<'a, T>;
134
135 fn into_iter(self) -> Items<'a, T> {
136 self.iter()
137 }
138}
139
140impl<T: Schema> FromIterator<T> for Stream<T> {
141 fn from_iter<I: IntoIterator<Item = T>>(items: I) -> Self {
142 let mut w = Stream::writer();
143 for item in items {
144 w.push(&item);
145 }
146 w.finish()
147 }
148}
149
150impl<T: Schema> From<Vec<T>> for Stream<T> {
151 fn from(items: Vec<T>) -> Self {
152 items.into_iter().collect()
153 }
154}
155
156impl<T> Clone for Stream<T> {
157 fn clone(&self) -> Self {
158 Stream::from_written(self.items.clone(), self.len)
159 }
160}
161
162impl<T> PartialEq for Stream<T> {
163 fn eq(&self, other: &Self) -> bool {
164 self.len == other.len && self.items == other.items
165 }
166}
167
168impl<T> Default for Stream<T> {
169 fn default() -> Self {
170 Stream::from_written(Vec::new(), 0)
171 }
172}
173
174impl<T> fmt::Debug for Stream<T> {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 write!(f, "Stream({} items, {} bytes)", self.len, self.items.len())
177 }
178}
179
180impl<T: Schema> Schema for Stream<T> {
181 fn shape() -> Shape {
182 Shape::List(T::shape)
183 }
184 /// The slow way (a text file, a value): read whole, then written.
185 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
186 let ValueRef::List(items) = v else {
187 cx.expected(crate::schema::Expected::List, v);
188 return None;
189 };
190 let mut w = Stream::writer();
191 let mut ok = true;
192 for (i, item) in items.iter().enumerate() {
193 match cx.at(Seg::Index(i), |cx| T::read(item, cx)) {
194 Some(x) => w.push(&x),
195 None => ok = false,
196 }
197 }
198 ok.then(|| w.finish())
199 }
200 /// The items that read, up to the first that does not: a `Value` has no
201 /// place for an error, so check a decoded stream with [`Stream::validate`].
202 fn write(&self) -> Value {
203 Value::List(
204 self.iter()
205 .map_while(Result::ok)
206 .map(|item| item.write())
207 .collect(),
208 )
209 }
210 fn encode(&self, w: &mut Writer) {
211 w.stream_body(self.len, &self.items);
212 }
213 /// Checks the framing only: the byte length, and that the count fits the
214 /// bytes (each item takes one at least, so a hostile count allocates
215 /// nothing). The items are read by [`Stream::iter`].
216 fn decode(d: &mut Decoder<'_>) -> Option<Self> {
217 let mut body = Decoder::body(d.stream()?);
218 let len = body.stream_count()?;
219 Some(Stream::from_written(body.rest().to_vec(), len))
220 }
221 /// In a frame it's a list, as its shape says (the items that read, as
222 /// in [`Stream::write`]).
223 fn pack(&self, p: &mut Packer) {
224 let items: Vec<T> = self.iter().map_while(Result::ok).collect();
225 T::pack_list(&items, p);
226 }
227 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
228 T::unpack_list(u).map(Stream::from)
229 }
230}