1

I'd like to write an asynchronous server in Rust using mio and I have trouble with the buffer types. I've tried different buffer types and can't get it to work. My current code is:

extern crate mio;
extern crate bytes;

use std::io;
use std::io::{Error, ErrorKind};
use std::net::SocketAddr;
use std::str::FromStr;
use std::io::Cursor;

use self::mio::PollOpt;
use self::mio::EventLoop;
use self::mio::EventSet;
use self::mio::Token;
use self::mio::Handler;
use self::mio::io::TryRead;
use self::mio::io::TryWrite;
//use self::mio::buf::ByteBuf;
//use self::mio::buf::Buf;
use self::mio::tcp::*;
use self::bytes::buf::Buf;
use self::bytes::buf::byte::ByteBuf;

struct EventHandler;

impl Handler for EventHandler {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<EventHandler>, token: Token, events: EventSet) {
    }
}

pub struct Connection {
    sock: TcpStream,
    send_queue: Vec<ByteBuf>,
}

impl Connection {
    pub fn writable(&mut self, event_loop: &mut EventLoop<EventHandler>) -> Result<(), String> {
        while !self.send_queue.is_empty() {
            if !self.send_queue.first().unwrap().has_remaining() {
                self.send_queue.pop();
            }
            let buf = self.send_queue.first_mut().unwrap();
            match self.sock.try_write_buf(&mut buf) {
                Ok(None) => {
                    return Ok(());
                }
                Ok(Some(n)) => {
                    continue;
                }
                Err(e) => {
                    return Err(format!("{}", e));
                }
            }
        }
    Ok(())
    }
}

fn main() {
    println!("Hello, world!");
}

The Cargo.toml contains the following dependencies:

mio = "*"
bytes = "*"

which currently translates to bytes 0.2.11 and mio 0.4.3 in Cargo.lock.

The error I am getting is this:

main.rs:45:29: 45:52 error: the trait `bytes::buf::Buf` is not implemented
            for the type `&mut bytes::buf::byte::ByteBuf` [E0277]
main.rs:45             match self.sock.try_write_buf(&mut buf) {

I'd want to be able to write a Vec<u8> into the socket and handle the case when the buffer is only partially written. How can I accomplish that?

I don't need explanation about the code that properly handles the return values, this question is about the buffer type. I have no idea which buffer type I have to use.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
elszben
  • 495
  • 1
  • 4
  • 6
  • I don't think it's possible to help you with just the information you posted. We would need at least your `Cargo.toml` to reproduce the problem, and you should also say what version of Rust you're using and exactly what errors you're getting. – fjh Oct 24 '15 at 09:08
  • Edited the question and added the error message. I know I am not using the proper types because rustc is complaining but I have no idea what type I should use to cover my use case. Rustc version rustc 1.5.0-nightly (9d3e79ad3 2015-10-10) – elszben Oct 24 '15 at 09:36

1 Answers1

2

The problem is this:

let buf = self.send_queue.first_mut().unwrap();
match self.sock.try_write_buf(&mut buf) {

You pass in an &mut &mut ByteBuf to try_write_buf because buf is already an &mut ByteBuf. Just drop the extra &mut:

let buf = self.send_queue.first_mut().unwrap();
match self.sock.try_write_buf(buf) {
fjh
  • 12,121
  • 4
  • 46
  • 46
  • Great, I totally missed that it is complaining about the reference and not the actual ByteBuf type and tried to import other Buf/ByteBuf pairs, hoping that it would compile... Did not even think of that! Thanks. It compiles now! – elszben Oct 24 '15 at 11:02