How do I choose an applicable when multiple applicable items exist in a scope

I would like to implement Read/Write trait from AsyncRead/AsyncWrite, since both of them have read method, rust can not select proper.

use pin_utils::pin_mut;
use std::cell::Cell;
use std::io::Result;
use std::io::{Read, Write};
use std::net::SocketAddr;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::Mutex;
use std::task::Context;
use std::task::Poll;
use tokio::net::UdpSocket;
use tokio::prelude::*;
use tokio_io::{AsyncRead, AsyncWrite};

impl Read for UdpStream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        match self.read(buf) { // Read should called from AsyncRead
            Poll::Pending => {},
            Poll::Ready(_) => {},
        };
        unimplemented!()
    }
}
impl Write for UdpStream {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        unimplemented!()
    }
    fn flush(&mut self) -> Result<()> {
        unimplemented!()
    }
}

impl AsyncRead for UdpStream {
    fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<usize>> {
        let mut socket = (&self.inner).lock().unwrap();
        let future = socket.recv_from(buf);
        //x.peer_addr.as_mut(); // = Some(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080));
        pin_mut!(future);
        future
            .poll(cx) // Poll<Result<(usize, SocketAddr)>>
            .map(|res| {
                res.map(|(count, address)| {
                    self.peer_addr.set(Some(address));
                    count
                })
            })
    }
}

impl AsyncWrite for UdpStream {
    fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
        //let addr = "127.0.0.1:7878";
        let mut socket = (&self.inner).lock().unwrap();
        let future = socket.send_to(buf, self.peer_addr().unwrap());
        pin_mut!(future);
        future.poll(cx)
    }
    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<()>> {
        Poll::Ready(Ok(()))
    }
    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<()>> {
        Poll::Ready(Ok(()))
    }
}

struct UdpStream {
    local_addr: Option<SocketAddr>,
    peer_addr: Cell<Option<SocketAddr>>,
    inner: Arc<Mutex<UdpSocket>>,
}

impl UdpStream {
    pub async fn connect(addr: &'static str) -> Result<Self> {
        dbg!(2);
        match UdpSocket::bind(addr).await {
            Ok(socket) => Ok({
                dbg!(3);
                {
                    Self {
                        local_addr: Some(socket.local_addr().unwrap()),
                        peer_addr: Cell::new(None),
                        inner: Arc::new(Mutex::new(socket)),
                    }
                }
            }),
            Err(_e) => unimplemented!(),
        }
    }
    pub fn local_addr(&self) -> Result<SocketAddr> {
        match self.local_addr {
            Some(addr) => Ok(addr),
            None => unimplemented!(),
        }
    }
    pub fn peer_addr(&self) -> Result<SocketAddr> {
        match self.peer_addr.get() {
            Some(addr) => Ok(addr),
            None => unimplemented!(),
        }
    }
}

use std::time::Duration;
use tokio::timer::Timeout;

use std::{thread, time};

use openssl::pkey::PKey;
use openssl::ssl::{SslAcceptor, SslConnector, SslMethod, SslVerifyMode};
use openssl::x509::X509;

static SERVER_CERT: &'static [u8] = include_bytes!("../server-cert.pem");
static SERVER_KEY: &'static [u8] = include_bytes!("../server-key.pem");
static SERVER_DOMAIN: &'static str = "server";

fn ssl_acceptor(certificate: &[u8], private_key: &[u8]) -> Result<SslAcceptor> {
    let mut acceptor_builder = SslAcceptor::mozilla_intermediate(SslMethod::dtls())?;
    acceptor_builder.set_certificate(&&X509::from_pem(certificate)?)?;
    acceptor_builder.set_private_key(&&PKey::private_key_from_pem(private_key)?)?;
    acceptor_builder.check_private_key()?;
    let acceptor = acceptor_builder.build();
    Ok(acceptor)
}

#[tokio::main]
async fn main() -> Result<()> {
    let acceptor = ssl_acceptor(SERVER_CERT, SERVER_KEY)?;
    dbg!(1);
    let mut stream = UdpStream::connect("127.0.0.1:8080").await?;
    dbg!(4);
    let mut buf = vec![0u8; 1024];
    acceptor.accept(stream);
    // loop {
    //     // let x = Timeout::new(stream.read(&mut buf), Duration::from_millis(10000)).await??;
    //     let x = stream.read(&mut buf).await?;
    //     stream.write(&buf[..x]).await?;
    // }
    Ok(())
}
error[E0034]: multiple applicable items in scope
  --> src/main.rs:25:20
   |
25 |         match self.read(buf) { // Read should called from AsyncRead
   |                    ^^^^ multiple `read` found
   |
note: candidate #1 is defined in an impl of the trait `std::io::Read` for the type `UdpStream`
  --> src/main.rs:24:5
   |
24 |     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: to disambiguate the method call, write `std::io::Read::read(&mut self, buf)` instead
   = note: candidate #2 is defined in an impl of the trait `tokio_io::io::async_read_ext::AsyncReadExt` for the type `_`
   = help: to disambiguate the method call, write `tokio_io::io::async_read_ext::AsyncReadExt::read(&mut self, buf)` instead
[dependencies]
tokio = "0.2.0-alpha"
tokio-openssl = "0.4.0-alpha"
tokio-io = "0.2.0-alpha"
pin-utils = "0.1.0-alpha"
openssl = "0.10"

The help message in the error message you posted tells you how to disambiguate what trait you want to call:

help: to disambiguate the method call, write `std::io::Read::read(&mut self, buf)` instead
help: to disambiguate the method call, write `tokio_io::io::async_read_ext::AsyncReadExt::read(&mut self, buf)` instead
3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.