1515//! * [`Object::read`] for side-car artifacts referenced by a
1616//! [`save::Handle`](super::save::Handle).
1717//!
18- //! [`Reader`] implements [`std::io::Read`] over a side-car artifact, regardless of the
19- //! provider's backing store.
18+ //! [`Reader`] implements [`std::io::Read`] and [`std::io::Seek`] over a side-car
19+ //! artifact, regardless of the provider's backing store.
2020
2121use std:: io:: BufReader ;
2222
@@ -30,7 +30,7 @@ use crate::{
3030///
3131/// A `LoadContext` supplies the root manifest [`save::Value`] ([`LoadContext::value`])
3232/// and resolves side-car artifacts referenced by handles ([`LoadContext::read`]). The
33- /// concrete implementations live under [ `crate::backend`] : a disk-backed context (under
33+ /// concrete implementations live under `crate::backend`: a disk-backed context (under
3434/// the `disk` feature) and an in-memory context. Alternative implementations (e.g. a
3535/// virtual filesystem) can be supplied for testing.
3636///
@@ -54,23 +54,35 @@ pub trait LoadContext {
5454 fn read ( & self , key : & str ) -> Result < Reader < ' _ > > ;
5555}
5656
57+ /// The backend-specific half of a [`Reader`].
58+ ///
59+ /// Each [`LoadContext`] implementation supplies its own `ReaderInner` (e.g. an in-memory
60+ /// cursor or an on-disk file). The blanket impl covers any type that is both
61+ /// [`std::io::Read`] and [`std::io::Seek`].
62+ pub ( crate ) trait ReaderInner : std:: io:: Read + std:: io:: Seek { }
63+
64+ impl < T > ReaderInner for T where T : std:: io:: Read + std:: io:: Seek { }
65+
5766/// A borrowed reader over a side-car artifact.
5867///
59- /// Produced by [`Object::read`]. Implements [`std::io::Read`] over whatever backing
60- /// store the [`LoadContext`] provides, so non-file-backed providers (like an in-memory byte buffer) can supply an
61- /// arbitrary [`std::io::Read`] .
68+ /// Produced by [`Object::read`]. Implements [`std::io::Read`] and [`std::io::Seek`] over
69+ /// whatever backing store the [`LoadContext`] provides, so non-file-backed providers
70+ /// (like an in-memory byte buffer) can supply an arbitrary seekable reader .
6271pub struct Reader < ' a > {
63- io : BufReader < Box < dyn std :: io :: Read + ' a > > ,
72+ io : BufReader < Box < dyn ReaderInner + ' a > > ,
6473}
6574
6675impl < ' a > Reader < ' a > {
67- /// Build a reader over an arbitrary borrowed [`std::io::Read `] source.
76+ /// Build a reader over an arbitrary borrowed [`ReaderInner `] source.
6877 ///
69- /// Used by non-file-backed [`LoadContext`] implementations (e.g. the in-memory
70- /// context) to expose a side-car artifact backed by a [`std::io::Cursor`].
71- pub ( crate ) fn new ( io : Box < dyn std:: io:: Read + ' a > ) -> Self {
78+ /// Used by [`LoadContext`] implementations to expose a side-car artifact backed by a
79+ /// file or an in-memory [`std::io::Cursor`].
80+ pub ( crate ) fn new < T > ( io : T ) -> Self
81+ where
82+ T : ReaderInner + ' a ,
83+ {
7284 Self {
73- io : BufReader :: new ( io ) ,
85+ io : BufReader :: new ( Box :: new ( io ) ) ,
7486 }
7587 }
7688}
@@ -96,6 +108,21 @@ impl std::io::Read for Reader<'_> {
96108 }
97109}
98110
111+ impl std:: io:: Seek for Reader < ' _ > {
112+ fn seek ( & mut self , pos : std:: io:: SeekFrom ) -> std:: io:: Result < u64 > {
113+ self . io . seek ( pos)
114+ }
115+ fn rewind ( & mut self ) -> std:: io:: Result < ( ) > {
116+ self . io . rewind ( )
117+ }
118+ fn stream_position ( & mut self ) -> std:: io:: Result < u64 > {
119+ self . io . stream_position ( )
120+ }
121+ fn seek_relative ( & mut self , offset : i64 ) -> std:: io:: Result < ( ) > {
122+ self . io . seek_relative ( offset)
123+ }
124+ }
125+
99126///////////////////////
100127// User facing types //
101128///////////////////////
0 commit comments