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 anyhow::{Context as _, Result, bail};
|
||||||
use std::{fs, io::{Read as _, Write as _}};
|
use std::{
|
||||||
|
fs,
|
||||||
|
io::{Read as _, Write as _},
|
||||||
|
};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let app = App::try_new()?;
|
let app = App::try_new()?;
|
||||||
|
@ -34,7 +37,7 @@ impl App {
|
||||||
return self.ls(".");
|
return self.ls(".");
|
||||||
}
|
}
|
||||||
for filename in &self.filenames {
|
for filename in &self.filenames {
|
||||||
let metadata = fs::metadata(&filename)?;
|
let metadata = fs::metadata(filename)?;
|
||||||
if metadata.is_dir() {
|
if metadata.is_dir() {
|
||||||
self.ls(filename)?;
|
self.ls(filename)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,16 +48,11 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cat(&self, filename: &str) -> Result<()> {
|
fn cat(&self, filename: &str) -> Result<()> {
|
||||||
let mut f = fs::File::open(filename)?;
|
let mut cat = Cat::try_new(filename)?;
|
||||||
let mut buf = vec![0u8; 4_096];
|
while let Some(buf) = cat.poll()? {
|
||||||
loop {
|
|
||||||
let bytes_read = f.read(&mut buf)?;
|
|
||||||
let buf = &buf[0..bytes_read];
|
|
||||||
if bytes_read == 0 {
|
|
||||||
break Ok(());
|
|
||||||
}
|
|
||||||
std::io::stdout().write_all(buf)?;
|
std::io::stdout().write_all(buf)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ls(&self, filename: &str) -> Result<()> {
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -80,7 +100,6 @@ mod tests {
|
||||||
fn test() -> Result<()> {
|
fn test() -> Result<()> {
|
||||||
let dir = tempfile::tempdir()?;
|
let dir = tempfile::tempdir()?;
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue