I have a function like this:
fn do_something(r: &mut Read) { ... }
Inside that function I need buffering to avoid small reads.
Currently I can do it like that:
let br = BufReader::new(r.by_ref());
work with br
In case r
is already buffered I'm getting double buffering here.
So I need to wrap r
in BufReader
only if r
is not yet buffered.
Is there any way to test if Read
is buffered and cast it to BufRead
?
My understanding is that trait Read
lacks a function like that:
trait Read {
...
// if `self` is `BufRead`, cast `self` to `BufRead`
fn as_buffered(&mut self) -> Option<&mut BufRead> { None }
}
so I could write my code like this:
use std::io::*;
fn buffered(_r: &mut Read) -> Option<&mut BufRead> {
// is it possible to implement it without patching rust std?
... cast or return None
}
fn do_something(read: &mut Read) {
let mut buf_reader_holder;
let buf_read;
if buffered(read).is_some() {
buf_read = buffered(read).unwrap();
} else {
buf_reader_holder = Some(BufReader::new(read));
buf_read = buf_reader_holder.as_mut().unwrap();
}
// do the reading
buf_read.lines();
}
fn main() {
my_func(&mut stdin());
}
Moreover Read
trait could provide a function like:
trait Read {
...
// Buffered adapter does own buffering only if `self` is not already buffered
fn buffered(&mut Stream) -> BufferedReadAdapter { ... }
}
Why can't I just take BufRead in the signature?
- It exposes function internals
- Sometimes it is not statically known whether
Read
is buffered or not, e. g. a function likeopen_http_get_stream(url: &str) -> HttpStreamReader
returns a stream that is buffered for SSL or zipped connection and not buffered otherwize.