Learning Rust 02: an ls clone
I'm learning Rust, and documenting the process. These posts are my notes - they're not guaranteed to be useful, interesting or correct!
In this post, I'm building an ls
clone. It's pretty similar to the last post's
pwd
clone. It's called rls
.
Code
use std::env;
use std::fs;
use std::process;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
usage();
}
let directory = &args[1];
let paths = fs::read_dir(directory).unwrap();
for path in paths {
let path_buf = path.unwrap().path();
let file_name = path_buf.file_name().unwrap();
println!("{}", file_name.to_string_lossy())
}
}
fn usage() {
eprintln!("usage: rls <dir>");
process::exit(1);
}
Fetching arguments
We can get the arguments passed to rls
with the env::args
function, which
returns an iterator. We can convert the iterator to a
vector, Rust's 'contiguous
growable array type'. I think vectors are the Rust equivalent to Go's slices, or
Python's lists. We assign this vector to a new variable, args
.
Input validation
We require that an argument is passed to rls
, the directory whose contents we
want to list. If this argument isn't supplied, we call usage
, which prints a
help message to stderr
and exits with a non-zero code, indicating an error.
Fetching a directory's contents
The standard library function fs::read_dir
returns an iterator of
Result<ReadDir>
, where ReadDir
is an iterator of io::Result<DirEntry>
s.
Printing the directories
We iterate over the ReadDir
, unwrap
each path, and pull the actual file name
out. Printing path_buf
would print the file path relative to the pwd -
ls
only prints file names. We print the file names with the println!
macro.
Error handling
Functions which interact with the file system are error-prone. That's why lots
of the values we get back from the file system functions are wrapped in
Results
. To use the success values, we need to handle the error case. We're
currently doing this using unwrap
, which panics if there's an error. This is
both verbose and bad UX - we probably don't want to display a full Rust error
message to our users.
It looks like there are a couple of ways of improving this - I'll be doing some reading about it here.