I want to keep a &mut impl Trait
or &mut dyn Trait
to a passed argument and the pass it along to other functions in my crate. Below is a stripped-down version of the code, to explain my situation.
extern crate byteorder; // 1.5.0
use core::fmt::Debug;
use std::io::{BufRead, BufReader, Cursor, Read, Seek, SeekFrom};
use std::error::Error;
pub trait BufReadExt : BufRead + Seek {
fn read_string_at_offset(&mut self, offset: u64) -> Result<String, Box<dyn Error>>{
let mut buf:Vec<u8> = Vec::new();
self.seek(SeekFrom::Start(offset))?;
self.read_until(b'\0', &mut buf)?;
Ok(String::from_utf8(buf[..(buf.len()-1)].to_vec())?)
}
}
impl Debug for dyn BufReadExt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "BufReadExt{{}}")
}
}
impl<T> BufReadExt for BufReader<T> where T: Read + Seek { }
impl<T> BufReadExt for Cursor<T> where T: AsRef<[u8]> { }
fn read_string(reader: &mut impl BufReadExt, offset: u64) -> Result<String, Box<dyn Error>>{
reader.read_string_at_offset(offset)
}
#[derive(Debug)]
struct MyStruct {
reader: mut dyn BufReadExt //How to I achieve this?
}
impl MyStruct {
pub fn read_a_string_at_0(&self) -> Result<String, Box<dyn Error>> {
read_string(&mut self.reader, 0)
}
}
fn main() {
let bytes = vec![0x41u8, 0x41, 0x41, 0x41, 0];
let mut cursor = Cursor::new(&bytes);
let res = read_string(&mut cursor, 0).unwrap();
let mst = MyStruct{ reader: cursor };
println!("{}", res);
assert_eq!(res, "AAAA");
}
Compiling playground v0.0.1 (/playground)
error: expected type, found keyword `mut`
--> src/main.rs:35:13
|
34 | struct MyStruct {
| -------- while parsing this struct
35 | reader: mut dyn BufReadExt //How to I achieve this?
| ^^^ expected type
error[E0609]: no field `reader` on type `&MyStruct`
--> src/main.rs:41:31
|
41 | read_string(&mut self.reader, 0)
| ^^^^^^ unknown field
For more information about this error, try `rustc --explain E0609`.
error: could not compile `playground` (bin "playground") due to 2 previous errors
Is this achievable?