#![crate_type = "bin"]
#![crate_name = "ls"]
#![feature(path_ext)]
static UTIL: Prog = Prog { name: "ls", vers: "0.1.0", yr: "2015" };
extern crate pgetopts;
extern crate rpf;
use pgetopts::{Options};
use rpf::{Status,Styled,PathMod,Prog,AsPath};
use std::fs;
use std::env;
use std::io;
use std::fs::{PathExt};
use std::path::{PathBuf};
enum Format {
Long,
Short,
}
fn is_dot(dir: &PathBuf) -> bool {
if dir.as_str().starts_with(".") {
return true;
} else {
return false;
}
}
fn format_print(rel_path: &PathBuf, path: &PathBuf, format: &Format) {
match format {
&Format::Short => {
if path.is_dir() {
print!("{}/ ", rel_path.as_str().bold());
} else {
print!("{} ", rel_path.display());
}
}
&Format::Long => {
if path.is_dir() {
println!("{}/ ", rel_path.as_str().bold());
} else {
println!("{} ", rel_path.display());
}
}
};
}
fn print(path: &Vec<String>, format: Format, all: bool) -> io::Result<()> {
for item in path.iter() {
if !item.as_path().exists() {
Status::Error.err(UTIL.name, String::from("\'".to_string() +
item +
"\' does not exist"));
}
let fpath = PathBuf::from(item);
if fpath.is_dir() {
for entry in try!(fs::read_dir(&fpath)) {
let entry = try!(entry);
let rel_path = entry.path().rel_to(&fpath);
match format {
Format::Short => {
if all {
format_print(&rel_path, &entry.path(), &format);
} else {
if !is_dot(&rel_path) {
format_print(&rel_path, &entry.path(), &format);
}
}
}
Format::Long => {
if all {
format_print(&rel_path, &entry.path(), &format);
} else {
if !is_dot(&rel_path) {
format_print(&rel_path, &entry.path(), &format);
}
}
}
};
}
} else if fpath.is_file() {
match format {
Format::Short => {
if all {
format_print(&fpath, &fpath, &format);
} else {
if !is_dot(&fpath) {
format_print(&fpath, &fpath, &format);
}
}
}
Format::Long => {
if all {
format_print(&fpath, &fpath, &format);
} else {
if !is_dot(&fpath) {
format_print(&fpath, &fpath, &format);
}
}
}
};
}
}
return Ok(());
}
fn print_usage(opts: Options) {
print!("{}: {} {}... {}...\n\
List information about the FILE(s)", "Usage".bold(), UTIL.name.bold(),
"[OPTION]".underline(), "FILE".underline());
println!("{}", opts.options());
}
fn main() {
let args: Vec<String> = env::args().collect();
let mut opts = Options::new();
opts.optflag("a", "all", "Display hidden files");
opts.optflag("h", "help", "Print help information");
opts.optflag("l", "long", "Use the long listing option");
opts.optflag("", "version", "Print version information");
let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }
Err(f) => {
Status::Error.err(UTIL.name, f.to_string());
panic!(f.to_string())
}
};
let mut current = Vec::new();
current.push(String::from(env::current_dir().unwrap().as_str()));
let all = matches.opt_present("a");
if matches.opt_present("h") {
print_usage(opts);
} else if matches.opt_present("version") {
UTIL.copyright("Copyright (C) 2015 core-utils developers\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
This is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\n",
vec!["Alberto Corona"]);
} else if matches.opt_present("l") {
if !matches.free.is_empty() {
print(&matches.free, Format::Long, all).ok();
} else {
print(¤t, Format::Long, all).ok();
}
} else {
if matches.free.is_empty() {
print(¤t, Format::Short, all).ok();
} else {
print(&matches.free, Format::Short, all).ok();
}
}
}