Simon
Simon

Reputation: 890

How to select the proper trait implementation in Rust?

I have a trait that expects either reqwest::Response or Vec as argument, only to throw them in a select::document::Document. To come to that end, I need to somehow get an implementation of io::Read for Vec<u8> in order to use Document::from_read.

Here's what I came up with:

use select::document::Document;
use std::{io::Read, io::Result};

#[derive(Debug)]
pub struct ReadableVec<T>(Vec<T>);

impl Read for ReadableVec<u8> {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        println!("Read!");
        let mut r: &[u8] = &self.0[..];
        r.read(buf)                           //< issue is here!!
    }
}

fn main() {
    let buf = ReadableVec(vec![60, 116]);
    let doc = Document::from_read(buf);
    println!("{:?}", doc)
}

My question is: why is r.read(buf) calling the Read implementation of ReadableVec instead of &[u8], thus making my function to recursively call itself? The type of r seems very clearly instructed by the line above.

PS: if there's a better solution to handle both Vec<u8> and reqwest::Response, it'll be appreciated in the comments! ;)

Upvotes: 0

Views: 637

Answers (1)

justinas
justinas

Reputation: 6857

You can disambiguate by referencing the trait method directly, e.g.:

use std::io::Read;

#[derive(Debug)]
pub struct ReadableVec<T>(Vec<T>);

impl Read for ReadableVec<u8> {
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        println!("Read!");
        Read::read(&mut &self.0[..], buf)
    }
}

fn main() {
    let mut buf = ReadableVec(vec![60, 116]);
    buf.read(&mut []);
}

This is called Universal Function Call Syntax (can't find this chapter in the new book, so I'm linking the first edition).

I do not think this is sufficient to make the implementation of Read correct though, as this would only advance the (temporary) slice. See my comment on Cursor.

Upvotes: 2

Related Questions