From ce0327fe57227caa57e4d62ef022b18b0e043630 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Fri, 21 Mar 2025 01:15:10 -0500 Subject: [PATCH] half-I/O cat --- src/main.rs | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6ea8553..e58a76c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ use anyhow::{Context as _, Result, bail}; -use std::{fs, io::{Read as _, Write as _}}; +use std::{ + fs, + io::{Read as _, Write as _}, +}; fn main() -> Result<()> { let app = App::try_new()?; @@ -34,7 +37,7 @@ impl App { return self.ls("."); } for filename in &self.filenames { - let metadata = fs::metadata(&filename)?; + let metadata = fs::metadata(filename)?; if metadata.is_dir() { self.ls(filename)?; } else { @@ -45,16 +48,11 @@ impl App { } fn cat(&self, filename: &str) -> Result<()> { - let mut f = fs::File::open(filename)?; - let mut buf = vec![0u8; 4_096]; - loop { - let bytes_read = f.read(&mut buf)?; - let buf = &buf[0..bytes_read]; - if bytes_read == 0 { - break Ok(()); - } + let mut cat = Cat::try_new(filename)?; + while let Some(buf) = cat.poll()? { std::io::stdout().write_all(buf)?; } + Ok(()) } fn ls(&self, filename: &str) -> Result<()> { @@ -72,6 +70,28 @@ impl App { } } +struct Cat { + f: fs::File, + buf: Vec, +} + +impl Cat { + fn try_new(filename: &str) -> Result { + let f = fs::File::open(filename)?; + let buf = vec![0u8; 4_096]; + Ok(Self { f, buf }) + } + + fn poll(&mut self) -> Result> { + let bytes_read = self.f.read(&mut self.buf)?; + let buf = &self.buf[0..bytes_read]; + if bytes_read == 0 { + return Ok(None); + } + Ok(Some(buf)) + } +} + #[cfg(test)] mod tests { use super::*; @@ -80,7 +100,6 @@ mod tests { fn test() -> Result<()> { let dir = tempfile::tempdir()?; - Ok(()) } }