half-I/O cat
parent
979dffac17
commit
ce0327fe57
41
src/main.rs
41
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<u8>,
|
||||
}
|
||||
|
||||
impl Cat {
|
||||
fn try_new(filename: &str) -> Result<Self> {
|
||||
let f = fs::File::open(filename)?;
|
||||
let buf = vec![0u8; 4_096];
|
||||
Ok(Self { f, buf })
|
||||
}
|
||||
|
||||
fn poll(&mut self) -> Result<Option<&[u8]>> {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue