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
readexists for structstd::net::TcpStream, but its trait bounds were not satisfied method cannot be called onstd::net::TcpStreamdue to unsatisfied trait bounds note: the following trait bounds were not satisfied:std::net::TcpStream: futures::AsyncReadwhich is required bystd::net::TcpStream: futures::AsyncReadExthelp: items from traits can only be used if the trait is in scoperustc(E0599) main.rs(31, 16): method cannot be called onstd::net::TcpStreamdue to unsatisfied trait bounds tcp.rs(49, 1): doesn't satisfystd::net::TcpStream: futures::AsyncReadExttcp.rs(49, 1): doesn't satisfystd::net::TcpStream: futures::AsyncReadmod.rs(580, 8): the method is available forstd::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...".
readmight be a method onRead(if using a sync tcp stream from the standard library) or onAsyncRead(viaAsyncReadExt). 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.