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}