use std::io; use std::io::Read; use std::thread::sleep; use std::time::Duration; type Result = std::result::Result>; #[derive(Debug)] struct Chunk { pub delta: i32, pub text: String, } impl Chunk { fn chunk32(chunk: &[u8; 8]) -> Result<(i32, i32)> { let (dc, sc) = { let (mut dc, mut sc): ([u8; 4], [u8; 4]) = ([0; 4], [0; 4]); for i in 0..4 { dc[i] = chunk[i]; sc[i] = chunk[i + 4]; } (dc, sc) }; let delta = i32::from_be_bytes(dc); let size = i32::from_be_bytes(sc); if delta < 0 || size < 1 || size > 100000 { return Err("delta source is not int32_t".into()); } Ok((delta, size)) } fn chunk64(dc: [u8; 8], sc: [u8; 4]) -> Result<(i32, i32)> { let delta = i64::from_be_bytes(dc); let size = i32::from_be_bytes(sc); if delta < 0 || delta > i32::MAX.into() || size < 1 || size > 100000 { return Err("delta source is not int64_t".into()); } let delta: i32 = delta.try_into()?; Ok((delta, size)) } pub fn read_chunk() -> Result { let mut stdin = io::stdin(); let mut chunk: [u8; 8] = [0; 8]; stdin.read_exact(&mut chunk)?; let (delta, size) = { if let Ok((delta, size)) = Self::chunk32(&chunk) { (delta, size) } else { let mut next_chunk: [u8; 4] = [0; 4]; stdin.read_exact(&mut next_chunk)?; if let Ok((delta, size)) = Self::chunk64(chunk, next_chunk) { (delta, size) } else { return Err("broken".into()); } } }; let mut text_chunk: Vec = vec![0; size as usize]; stdin.read_exact(&mut text_chunk)?; let text = String::from_utf8(text_chunk)?; Ok(Self { delta, text }) } } fn main() -> Result<()> { while let Ok(chunk) = Chunk::read_chunk() { sleep(Duration::from_millis(chunk.delta.try_into()?)); print!("{}", chunk.text); } println!(); Ok(()) }