flexible_io/
reader.rs

1use crate::stable_with_metadata_of::WithMetadataOf;
2
3use std::{
4    any::Any,
5    io::{BufRead, Read, Seek},
6};
7
8/// A reader, which can dynamically provide IO traits.
9///
10/// The following traits may be optionally dynamically provided:
11///
12/// * [`Seek`]
13/// * [`BufRead`]
14/// * [`Any`]
15///
16/// The struct comes with a number of setter methods. The call to these requires proof to the
17/// compiler that the bound is met, inserting the vtable from the impl instance. Afterward, the
18/// bound is not required by any user. Using the (mutable) getters recombines the vtable with the
19/// underlying value.
20///
21/// Note that the value can not be unsized (`dyn` trait) itself. This may be fixed at a later point
22/// to make the reader suitable for use in embedded. In particular, the double indirection of
23/// instantiating with `R = &mut dyn Read` wouldn't make sense as the setters would not be usable,
24/// their bounds can never be met. And combining traits into a large dyn-trait is redundant as it
25/// trait-impls become part of the static validity requirement again.
26///
27/// ## Usage
28///
29/// ```
30/// # use flexible_io::Reader;
31/// let mut buffer: &[u8] = b"Hello, world!";
32/// let mut reader = Reader::new(&mut buffer);
33/// assert!(reader.as_buf().is_none());
34///
35/// // But slices are buffered readers, let's tell everyone.
36/// reader.set_buf();
37/// assert!(reader.as_buf().is_some());
38///
39/// // Now use the ReadBuf implementation directly
40/// let buffered = reader.as_buf_mut().unwrap();
41/// buffered.consume(7);
42/// assert_eq!(buffered.fill_buf().unwrap(), b"world!");
43/// ```
44pub struct Reader<R> {
45    inner: R,
46    read: *mut dyn Read,
47    vtable: OptTable,
48}
49
50#[derive(Clone, Copy)]
51struct OptTable {
52    seek: Option<*mut dyn Seek>,
53    buf: Option<*mut dyn BufRead>,
54    any: Option<*mut dyn Any>,
55}
56
57/// A mutable reference to a [`Reader`].
58///
59/// This type acts similar to a *very* fat mutable reference. It can be obtained by constructing a
60/// concrete reader type and calling [`Reader::as_mut`].
61///
62/// Note: Any mutable reference to a `Reader` implements `Into<ReaderMut>` for its lifetime. Use
63/// this instead of coercion which would be available if this was a builtin kind of reference.
64///
65/// Note: Any `Reader` implements `Into<ReaderBox>`, which can again be converted to [`ReaderMut`].
66/// Use it for owning a writer without its specific type similar to `Box<dyn Write>`.
67pub struct ReaderMut<'lt> {
68    inner: &'lt mut dyn Read,
69    vtable: OptTable,
70}
71
72/// A box around a type-erased [`Reader`].
73pub struct ReaderBox<'lt> {
74    inner: Box<dyn Read + 'lt>,
75    vtable: OptTable,
76}
77
78impl<R: Read> Reader<R> {
79    /// Wrap an underlying reader by-value.
80    pub fn new(mut reader: R) -> Self {
81        let read = lifetime_erase_trait_vtable!((&mut reader): '_ as Read);
82
83        Reader {
84            inner: reader,
85            read,
86            vtable: OptTable {
87                seek: None,
88                buf: None,
89                any: None,
90            },
91        }
92    }
93}
94
95impl<R> Reader<R> {
96    /// Provide access to the underlying reader.
97    pub fn get_ref(&self) -> &R {
98        &self.inner
99    }
100
101    /// Provide mutable access to the underlying reader.
102    pub fn get_mut(&mut self) -> &mut R {
103        &mut self.inner
104    }
105
106    /// Get a view equivalent to very-fat mutable reference.
107    ///
108    /// This erases the concrete type `R` which allows consumers that intend to avoid polymorphic
109    /// code that monomorphizes. The mutable reference has all accessors of a mutable reference
110    /// except it doesn't offer access with the underlying reader's type itself.
111    pub fn as_mut(&mut self) -> ReaderMut<'_> {
112        // Copy out all the vtable portions, we need a mutable reference to `self` for the
113        // conversion into a dynamically typed `&mut dyn Read`.
114        let Reader {
115            inner: _,
116            read: _,
117            vtable,
118        } = *self;
119
120        ReaderMut {
121            inner: self.as_read_mut(),
122            vtable,
123        }
124    }
125
126    /// Get an allocated, type-erased very-fat mutable box.
127    ///
128    /// This erases the concrete type `R` which allows consumers that intend to avoid polymorphic
129    /// code that monomorphizes. The mutable reference has all accessors of a mutable reference
130    /// except it doesn't offer access with the underlying reader's type itself.
131    pub fn into_boxed<'lt>(self) -> ReaderBox<'lt>
132    where
133        R: 'lt,
134    {
135        let Reader {
136            inner,
137            read,
138            vtable,
139        } = self;
140
141        let ptr = Box::into_raw(Box::new(inner));
142        let ptr = WithMetadataOf::with_metadata_of_on_stable(ptr, read);
143        let inner = unsafe { Box::from_raw(ptr) };
144
145        ReaderBox { inner, vtable }
146    }
147
148    /// Set the V-Table for [`BufRead`].
149    ///
150    /// After this call, the methods [`Self::as_buf`] and [`Self::as_buf_mut`] will return values.
151    pub fn set_buf(&mut self)
152    where
153        R: BufRead,
154    {
155        self.vtable.buf = Some(lifetime_erase_trait_vtable!((&mut self.inner): '_ as BufRead));
156    }
157
158    /// Set the V-Table for [`Seek`].
159    ///
160    /// After this call, the methods [`Self::as_seek`] and [`Self::as_seek_mut`] will return values.
161    pub fn set_seek(&mut self)
162    where
163        R: Seek,
164    {
165        self.vtable.seek = Some(lifetime_erase_trait_vtable!((&mut self.inner): '_ as Seek));
166    }
167
168    /// Set the V-Table for [`Any`].
169    ///
170    /// After this call, the methods [`Self::as_any`] and [`Self::as_any_mut`] will return values.
171    pub fn set_any(&mut self)
172    where
173        R: Any,
174    {
175        self.vtable.any = Some(lifetime_erase_trait_vtable!((&mut self.inner): '_ as Any));
176    }
177}
178
179impl<R> Reader<R> {
180    /// Get the inner value as a dynamic `Read` reference.
181    pub fn as_read(&self) -> &(dyn Read + '_) {
182        let ptr = &self.inner as *const R;
183        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.read);
184        unsafe { &*local }
185    }
186
187    /// Get the inner value as a mutable dynamic `Read` reference.
188    pub fn as_read_mut(&mut self) -> &mut (dyn Read + '_) {
189        let ptr = &mut self.inner as *mut R;
190        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.read);
191        unsafe { &mut *local }
192    }
193
194    /// Get the inner value as a dynamic `BufRead` reference.
195    ///
196    /// This returns `None` unless a previous call to [`Self::set_buf`] as executed, by any other caller.
197    /// The value can be moved after such call arbitrarily.
198    pub fn as_buf(&self) -> Option<&(dyn BufRead + '_)> {
199        let ptr = &self.inner as *const R;
200        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
201        Some(unsafe { &*local })
202    }
203
204    /// Get the inner value as a mutable dynamic `BufRead` reference.
205    ///
206    /// This returns `None` unless a previous call to [`Self::set_buf`] as executed, by any other caller.
207    /// The value can be moved after such call arbitrarily.
208    pub fn as_buf_mut(&mut self) -> Option<&mut (dyn BufRead + '_)> {
209        let ptr = &mut self.inner as *mut R;
210        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
211        Some(unsafe { &mut *local })
212    }
213
214    /// Get the inner value as a dynamic `Seek` reference.
215    ///
216    /// This returns `None` unless a previous call to [`Self::set_seek`] as executed, by any other caller.
217    /// The value can be moved after such call arbitrarily.
218    pub fn as_seek(&self) -> Option<&(dyn Seek + '_)> {
219        let ptr = &self.inner as *const R;
220        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
221        Some(unsafe { &*local })
222    }
223
224    /// Get the inner value as a mutable dynamic `Seek` reference.
225    ///
226    /// This returns `None` unless a previous call to [`Self::set_seek`] as executed, by any other caller.
227    /// The value can be moved after such call arbitrarily.
228    pub fn as_seek_mut(&mut self) -> Option<&mut (dyn Seek + '_)> {
229        let ptr = &mut self.inner as *mut R;
230        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
231        Some(unsafe { &mut *local })
232    }
233
234    /// Get the inner value as a dynamic `Any` reference.
235    pub fn as_any(&self) -> Option<&'_ dyn Any> {
236        let ptr = &self.inner as *const R;
237        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
238        Some(unsafe { &*local })
239    }
240
241    /// Get the inner value as a dynamic `Any` reference.
242    pub fn as_any_mut(&mut self) -> Option<&'_ mut dyn Any> {
243        let ptr = &mut self.inner as *mut R;
244        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
245        Some(unsafe { &mut *local })
246    }
247
248    /// Unwrap the inner value at its original sized type.
249    pub fn into_inner(self) -> R {
250        self.inner
251    }
252}
253
254impl ReaderMut<'_> {
255    pub fn as_read_mut(&mut self) -> &mut (dyn Read + '_) {
256        &mut *self.inner
257    }
258
259    pub fn as_buf_mut(&mut self) -> Option<&mut (dyn BufRead + '_)> {
260        let ptr = self.inner as *mut dyn Read;
261        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
262        Some(unsafe { &mut *local })
263    }
264
265    pub fn as_seek_mut(&mut self) -> Option<&mut (dyn Seek + '_)> {
266        let ptr = self.inner as *mut dyn Read;
267        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
268        Some(unsafe { &mut *local })
269    }
270
271    /// Get the inner value as a dynamic `Any` reference.
272    pub fn as_any(&self) -> Option<&'_ dyn Any> {
273        let ptr = self.inner as *const dyn Read;
274        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
275        Some(unsafe { &*local })
276    }
277
278    /// Get the inner value as a dynamic `Any` reference.
279    pub fn as_any_mut(&mut self) -> Option<&'_ mut dyn Any> {
280        let ptr = self.inner as *mut dyn Read;
281        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
282        Some(unsafe { &mut *local })
283    }
284}
285
286impl ReaderBox<'_> {
287    pub fn as_mut(&mut self) -> ReaderMut<'_> {
288        ReaderMut {
289            vtable: self.vtable,
290            inner: self.as_read_mut(),
291        }
292    }
293
294    pub fn as_read_mut(&mut self) -> &mut (dyn Read + '_) {
295        &mut *self.inner
296    }
297
298    pub fn as_buf_mut(&mut self) -> Option<&mut (dyn BufRead + '_)> {
299        let ptr = self.inner.as_mut() as *mut _;
300        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.buf?);
301        Some(unsafe { &mut *local })
302    }
303
304    pub fn as_seek_mut(&mut self) -> Option<&mut (dyn Seek + '_)> {
305        let ptr = self.inner.as_mut() as *mut _;
306        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.seek?);
307        Some(unsafe { &mut *local })
308    }
309
310    /// Get the inner value as a dynamic `Any` reference.
311    pub fn as_any(&self) -> Option<&'_ dyn Any> {
312        let ptr = self.inner.as_ref() as *const _;
313        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
314        Some(unsafe { &*local })
315    }
316
317    /// Get the inner value as a dynamic `Any` reference.
318    pub fn as_any_mut(&mut self) -> Option<&'_ mut dyn Any> {
319        let ptr = self.inner.as_mut() as *mut _;
320        let local = WithMetadataOf::with_metadata_of_on_stable(ptr, self.vtable.any?);
321        Some(unsafe { &mut *local })
322    }
323}
324
325impl<'lt, R> From<&'lt mut Reader<R>> for ReaderMut<'lt> {
326    fn from(value: &'lt mut Reader<R>) -> Self {
327        value.as_mut()
328    }
329}
330
331impl<'lt, R: 'lt> From<Reader<R>> for ReaderBox<'lt> {
332    fn from(value: Reader<R>) -> Self {
333        value.into_boxed()
334    }
335}
336
337impl<'lt> From<&'lt mut ReaderBox<'_>> for ReaderMut<'lt> {
338    fn from(value: &'lt mut ReaderBox<'_>) -> Self {
339        value.as_mut()
340    }
341}