Open ultrasaurus opened 5 years ago
let mut response = String::new();
let reader = tokio::io::BufReader::new(stream);
reader.read_line(response).await?;
Alternatively, with fewer moving parts but less flexibility:
let mut response = [0; 64];
stream.read_exact(&mut response).await?;
Thanks @krisselden for the read_line hint, this worked:
let mut response = String::new();
let mut reader = tokio::io::BufReader::new(stream);
reader.read_line(&mut response).await?;
println!("response: {}", response);
full code here
@Ralith I really like the one-liner... how would it work where 64
is a variable?
in my example, I'm expecting the following response (when I connect with my twitter account):
:ultrasaurus_twitter!ultrasaurus_twitter@irc.gitter.im NICK :ultrasaurus_twitter
but "ultrasaurus_twitter" is dynamically determined by the USER
environment variable, so I think I would want to do something like:
let read_len = irc_user.len() * 3 + "!@irc.gitter.im NICK :".len() + 2;
let mut response = String::with_capacity(read_len);
stream.read_exact(&mut response).await?;
println!("response: {}", response);
but I get this compile error:
error[E0308]: mismatched types
--> src/main.rs:33:23
|
33 | stream.read_exact(&mut response).await?;
| ^^^^^^^^^^^^^ expected slice, found struct `std::string::String`
|
= note: expected type `&mut [u8]`
found type `&mut std::string::String`
I tried changing to Bytes, but still couldn't get it to work.... what syntax am I missing for this approach?
read_exact
is only suitable if you know the exact length of the data in advance, which is not the case for IRC. The type error you're getting can be resolved by using Vec<u8>
or Bytes
and passing it as &mut response[..]
, but for a protocol like IRC you should really use read_line
instead. Or better yet, a version of read_line
which bails out if it receives more than a maximum amount of data (iirc IRC caps out at 512 bytes per command) so that a malicious or buggy server can't DoS you.
Currently there is a TcpStream doc example of a one-liner that writes to a stream"
What would be an equivalent one-liner for read? (it could be read-N-bytes or read_until) I tried with read_lines, but it doesn't compile:
see full source, which fails with this error:
How do I satisfy the trait bounds for
AsyncBufReadExt
? or is there a different / better approach?