read_to_eof/
read_to_eof.rs

1use std::io::prelude::*;
2use std::net::TcpStream;
3use std::str;
4
5use rotating_buffer::RotatingBuffer;
6
7fn main() -> std::io::Result<()> {
8    // Unusually small, but we're just proving a point here. Let's just assume we have incredibly
9    // limited bandwidth and flexible value lengths, separated by a comma
10    let mut buf = RotatingBuffer::<u8, 5>::new();
11
12    let mut stream = TcpStream::connect("127.0.0.1:34254")?;
13
14    loop {
15        let read_size = stream.read(buf.get_append_only())?;
16        if read_size != 0 {
17            // read_size and _buf_size may diverge because add_len extends data that was
18            // right-rotated previously
19            let _buf_size = buf.add_len(read_size);
20        }
21
22        // .as_slice() will provide a slice combining previous right-rotated
23        // data as well as newly written data
24        let incoming = str::from_utf8(buf.as_slice()).unwrap();
25
26        // Print every comma separated value on a separate line, even if the buffer is too small to
27        // hold the entire value, except if it's "EOF\n"
28        if !incoming.ends_with("EOF\n") && read_size != 0 || incoming.len() > 4 {
29            if let Some(index) = incoming.rfind(',') {
30                for value in incoming[..index].split(',') {
31                    println!("{}", value);
32                }
33                // Do not include the comma when rotating and resizing
34                buf.rotate_right_and_resize_at(index + 1);
35            } else {
36                // Here we could push to a heap-allocated structure if appropriate, but we'd need to
37                // adapt the logic above to account for when this value is completed by a comma
38                print!("{}", incoming);
39                buf.resize(0);
40            }
41        } else {
42            return Ok(());
43        }
44    }
45}