File tree Expand file tree Collapse file tree 2 files changed +37
-0
lines changed Expand file tree Collapse file tree 2 files changed +37
-0
lines changed Original file line number Diff line number Diff line change 2
2
//! This module contains tools needed mostly in services layers.
3
3
4
4
mod progress_reporter;
5
+ mod stream_reader;
5
6
mod unpacker;
6
7
7
8
pub use progress_reporter:: * ;
9
+ pub use stream_reader:: * ;
8
10
pub use unpacker:: * ;
Original file line number Diff line number Diff line change
1
+ use flume:: Receiver ;
2
+ use std:: io;
3
+
4
+ // Credits and many thanks to https://stackoverflow.com/a/69967522 for most of this code
5
+
6
+ /// A channel receiver that implement [io::Read].
7
+ pub struct StreamReader {
8
+ receiver : Receiver < Vec < u8 > > ,
9
+ current : io:: Cursor < Vec < u8 > > ,
10
+ }
11
+
12
+ impl StreamReader {
13
+ /// [StreamReader] factory
14
+ pub fn new ( receiver : Receiver < Vec < u8 > > ) -> Self {
15
+ Self {
16
+ receiver,
17
+ current : io:: Cursor :: new ( vec ! [ ] ) ,
18
+ }
19
+ }
20
+ }
21
+
22
+ impl io:: Read for StreamReader {
23
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
24
+ if self . current . position ( ) == self . current . get_ref ( ) . len ( ) as u64 {
25
+ // We've exhausted the previous chunk, get a new one.
26
+ if let Ok ( vec) = self . receiver . recv ( ) {
27
+ self . current = io:: Cursor :: new ( vec) ;
28
+ }
29
+ // If recv() "fails", it means the sender closed its part of
30
+ // the channel, which means EOF. Propagate EOF by allowing
31
+ // a read from the exhausted cursor.
32
+ }
33
+ self . current . read ( buf)
34
+ }
35
+ }
You can’t perform that action at this time.
0 commit comments