Deboxing std::io::Read

Hi,

as a total newbie to rust i started to play around with some code that i found on github. So i decided to make a cmd tool (my version) for a published library and i got stuck immediately :frowning:

the thing i am trying to do is to pass a Read object to an object in that lib using the following boilerplate:

extern crate parser;
use parser::Parser;

MyObj {
  parser_obj: Parser<&mut dyn Read>
}


impl  MyObj {

  pub fn new<T: AsRef<Path>>(filename: Option<T>) -> Self {

    let mut reader: Box<dyn Read> = match filename {
      None => Box::new(std::io::stdin()),
      Some(x) => Box::new(std::fs::File::open(x).unwrap()),
    };
    let parser = Parser::new(&mut reader);
    MyObj{
      parser_obj: parser
    }
  }
}

The Error i get is quite obvious one :

error[E0308]: mismatched types
  --> src/lib.rs:54:21
   |
54 |             parser_obj: parser,
   |                                  ^^^^^^ expected trait object `dyn std::io::Read`, found struct `Box`
   |
   = note: expected struct `Parser<&mut dyn std::io::Read>`
              found struct `Parser<&mut Box<dyn std::io::Read>>`

But i have difficulty finding a workaround. I know that unfortunately Read is a trait so i cannot pass it by value. The easiest alternative is to do heap allocation. But if i do it how do i fix the Parser (struct not written by me and i have to use it as is )

Any insight ?

Can't you use Parser<Box<dyn Read>> instead? I wasn't able to find the definitions for the external crate, so I'm not sure whether this would satisfy the requirements, but it seems to be the most obvious way to go for now.

In general you can force the cast by saying something like &mut reader as &mut dyn Read, but in this case you probably want Parser<Box<dyn Read>>, since returning a reference to a local variable won't work.

1 Like

Actually, the conversion doesn't even require a cast or a forced coercion. The box already contains mut dyn Read, so it should be as easy as &mut *reader.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.