0

SOLUTION: I needed to add "use std::io::prelude::*;" to my code. I do not know why.

I am trying to read from an std::net::TcpStream but I recieve this error when calling stream.read(&buf).unwrap;

the method read exists for struct std::net::TcpStream, but its trait bounds were not satisfied method cannot be called on std::net::TcpStream due to unsatisfied trait bounds note: the following trait bounds were not satisfied: std::net::TcpStream: futures::AsyncRead which is required by std::net::TcpStream: futures::AsyncReadExt help: items from traits can only be used if the trait is in scoperustc(E0599) main.rs(31, 16): method cannot be called on std::net::TcpStream due to unsatisfied trait bounds tcp.rs(49, 1): doesn't satisfy std::net::TcpStream: futures::AsyncReadExt tcp.rs(49, 1): doesn't satisfy std::net::TcpStream: futures::AsyncRead mod.rs(580, 8): the method is available for std::boxed::Box<std::net::TcpStream> here

Code:

use irc::client::prelude::*; use futures::prelude::*; use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream}; use std::io; use futures::{AsyncRead, AsyncReadExt}; const NAME: &str = "nickname"; #[derive(Debug)] struct DCC { ip: IpAddr, port: u16, } impl DCC { fn from_msg(msg: &str) -> Result<DCC, std::num::ParseIntError> { let msg_split: Vec<&str> = msg.split_whitespace().collect(); let ip: u32 = msg_split[3].parse()?; let ip_addr: IpAddr = IpAddr::V4(Ipv4Addr::from(ip)); let port_num: u16 = msg_split[4].parse()?; let dcc = DCC{ ip: ip_addr, port: port_num, }; return Ok(dcc); } async fn connect(&self) -> Result<(), io::Error>{ let socket_addr = SocketAddr::new(self.ip, self.port); let mut socket = TcpStream::connect(socket_addr)?; let mut buf = vec![]; socket.read(&buf).unwrap(); return Err(io::Error::new(io::ErrorKind::Other, "oh no!")); } } #[tokio::main] async fn irc_get(name: &str) -> Result<String, irc::error::Error>{ let config = Config { nickname: Some(NAME.to_owned()), server: Some("irc.irchighway.net".to_owned()), port: Some(6667), use_tls: Some(false), channels: vec!["#ebooks".to_owned()], ..Config::default() }; let mut client = Client::from_config(config).await?; client.identify()?; let mut stream = client.stream()?; //waits for server to log us in and then sends the search request loop{ let m = match stream.next().await{ Some(v) => v, None => panic!("at the disco") }; let message = match &m { Ok(message) => match &message.command {Command::NOTICE(_s1, s2)=> {print!("{:?} \n", s2); message}, _ => message}, Err(_e) => panic!("at the disco")}; match &message.command{ Command::NOTICE(_s, msg) => { if msg.contains("Welcome to #ebooks"){break}}, _=> () } } client.send_privmsg("#ebooks", format!["@Search {}", name])?; loop{ let m = match stream.next().await.transpose()?{ Some(m) => m, None => panic!("at the disco") }; match &m.command{ Command::PRIVMSG(nm, msg) => if nm == NAME {println!("{:?}",m); return Ok(String::from(msg))}, _ => () } } } fn main() { let dcc = DCC::from_msg(&irc_get(&"romeo and juliet").unwrap()[..]); println!("{:?}", dcc); } 

I'm fairly new at rust and based on all of the examples in the documentation I think I'm using .read correctly. My only thought is that maybe it's because I'm trying to write the code in the impl, but I don't know if rust treats that differently. It also fails with "async fn connect..." and with "fn connect...".

3
  • 1
    It's hard to know what you're doing without a minimal reproduction example, and at the very east the entire error message*. But you seem to be mixing synchronous and asynchronous APIs which doesn't help. One very relevant thing in Rust is that trait methods require the trait to be in scope. read might be a method on Read (if using a sync tcp stream from the standard library) or on AsyncRead (via AsyncReadExt). The corresponding trait(s) need to be imported explicitely (possibly via a "prelude import" but I dislike that in long-term cases) in order for the method to be accessible. Commented May 14, 2021 at 13:55
  • Edited question with full error message and all my code (including the new import statement suggested in the answer below (which did not fix the error)). Commented May 14, 2021 at 14:01
  • This is also not my first rust project, I already built a complet web application backend with user login and postgressql. So while I am new, I am at least familiar with rust and I have read just under half of the rustbook so far. Commented May 14, 2021 at 14:02

1 Answer 1

0

The compiler was telling you the solution:

help: items from traits can only be used if the trait is in scope

You need to import the traits in order to use them:

use futures::{AsyncRead, AsyncReadExt}; 

Also you would probably want to use tokio::TcpStream which is async and not the std one.

Sign up to request clarification or add additional context in comments.

2 Comments

I added that and it did not fix it. I have edited my question with an unabridged error message which seems to claim that the error is in the TcpStream itself. That however seems ...unlikely.
@aghayes, I added that you may need tokio one instead of std for async.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.