TcpStream prints different data

Hi, I am new to rust and just figuring out how it works. While digging the http server example at the end of the rust book, i got different outputs between these codes:

fn handle_connection(mut stream: TcpStream) {
    let buf_reader = BufReader::new(&mut stream);
    println!("{:#?}", buf_reader);

when i print out the buf_reader here, i got this:

BufReader {
    reader: TcpStream {
        addr: 127.0.0.1:7878,
        peer: 127.0.0.1:43336,
        fd: 5,
    },
    buffer: 0/8192,
}

and when i try to print like this

println!("{:#?}", buf_reader
    .lines()
    .map(|result| result.unwrap())
    .take_while(|line| !line.is_empty())

i got this

TakeWhile {
    iter: Map {
        iter: Lines {
            buf: BufReader {
                reader: TcpStream {
                    addr: 127.0.0.1:7878,
                    peer: 127.0.0.1:43336,
                    fd: 5,
                },
                buffer: 0/8192,
            },
        },
    },
    flag: false,
}

and when i use it by declaring a vector variable like this

let  request: Vec<_> =  buf_reader
    .lines()
    .map(|result| result.unwrap())
    .take_while(|line| !line.is_empty())
    .collect();

    println!("{:#?}", request);

i got the correct output which includes header info

[
    "GET / HTTP/1.1",
    "Host: 127.0.0.1:7878",
    "Connection: keep-alive",
    "Cache-Control: max-age=0",
    "sec-ch-ua: \"Chromium\";v=\"128\", \"Not;A=Brand\";v=\"24\", \"Google Chrome\";v=\"128\"",
    "sec-ch-ua-mobile: ?0",
    "sec-ch-ua-platform: \"Linux\"",
    "Upgrade-Insecure-Requests: 1",
    "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Sec-Fetch-Site: none",
    "Sec-Fetch-Mode: navigate",
    "Sec-Fetch-User: ?1",
    "Sec-Fetch-Dest: document",
    "Accept-Encoding: gzip, deflate, br, zstd",
    "Accept-Language: en-US,en-GB;q=0.9,en;q=0.8,tr;q=0.7",
]

I am just curious why these outputs are different. a little help much appreciated. thank you

Because in the first example you're printing an Iterator.
Iterators are evaluated lazily. If you want their elements, you actually need to consume them, either by calling .next() on them until they are exhausted, for-looping over them, or by collecting them into a collection, as you did in the second example.

1 Like

A TcpStream - and most Read types for that matter - are data sources. Something that can get you some data if you ask for it, possibly only once. A Vec is data you already have and can operate on as often as you want.

So debug-printing a data source would be a destructive operation if it would consume the data. This isn't an issue for a Vec.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.