A std::io::Cursor has two main elements - the underlying buffer (a Vec<u8> in this case) and a u64 which points at the "current location" in that buffer.
Think of it like a file.
When you write, you are writing to the end of the buffer, and because you are still at the end of the buffer after the write, there is nothing left to read.
Note that although the accepted answer doesn't correct that mistake, you still should be using read_exact() instead of read(), or you should at least not ignore the return value of read(). From the docs:
Pull some bytes from this source into the specified buffer, returning how many bytes were read
[…]
It is not an error if the returned value n is smaller than the buffer size, even when the reader is not at the end of the stream yet. This may happen for example because fewer bytes are actually available right now (e. g. being close to end-of-file) or because read() was interrupted by a signal.
As this trait is safe to implement, callers in unsafe code cannot rely on n <= buf.len() for safety. Extra care needs to be taken when unsafe functions are used to access the read bytes. Callers have to ensure that no unchecked out-of-bounds accesses are possible even if n > buf.len().
No guarantees are provided about the contents of buf when this function is called, so implementations cannot rely on any property of the contents of buf being true. It is recommended that implementations only write data to buf instead of reading its contents.
Just as a follow-up: This is what I ended up going with, because the cursor didn't really provide all the functionality I needed since I needed to permanently consume the data being read. I just use Take on a Vec<u8> and then set the Vec<u8> to a slice without the read portion.
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
fn main() {
let mut cursor: Vec<u8> = Vec::new();
let write_size = cursor.write(b"Hello\n").expect("couldn't write");
//internal.extend_from_slice(format!("{x}").as_bytes());
let mut buf: Vec<u8> = vec![0; 6];
let mut buf = [0u8; 6];
dbg!(write_size);
dbg!(String::from_utf8_lossy(&cursor));
dbg!(String::from_utf8_lossy(&buf));
let Ok(read_size) = cursor.take(buf.len() as u64).read(&mut buf) else {
eprintln!("Unable to read");
return;
};
cursor = cursor[read_size..].into();
dbg!(read_size);
dbg!(String::from_utf8_lossy(&cursor));
dbg!(String::from_utf8_lossy(&buf));
}