core-utils 0.1.2

A reimplementation of the GNU core utils in the Rust programming language
// Copyright (C) 2015, Alberto Corona <ac@albertocorona.com>
// All rights reserved. This file is part of core-utils, distributed under the
// GPL v3 license. For full terms please see the LICENSE file.

#![crate_type = "bin"]
#![crate_name = "mv"]
#![feature(path_ext,slice_splits)]

static UTIL: Prog = Prog { name: "mv", vers: "0.1.0", yr: "2015" };

extern crate pgetopts;
extern crate rpf;

use pgetopts::{Options};
use rpf::{Status,Styled,Prog,AsPath};

use std::env;
use std::fs;
use std::fs::{PathExt};
use std::path::{PathBuf};

fn rename(from: PathBuf, to: PathBuf) {
    match fs::rename(from, to) {
        Ok(s) => { s },
        Err(e) => {
            Status::Error.err(UTIL.name, e.to_string());
        }
    }
}

fn print_usage(opts: Options) {
    print!("{}: {} {} {} {}\n\
           Rename SOURCE to DEST", "Usage".bold(), UTIL.name.bold(),
           "[OPTION]".underline(), "SOURCE".underline(), "DEST".underline());
    println!("{}", opts.options());
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();

    opts.optflag("h", "help", "Print help information");
    opts.optflag("", "version", "Print version information");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m },
        Err(e) => {
            Status::OptError.err(UTIL.name, e.to_string());
            panic!(e.to_string())
        }
    };

    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 {
        match matches.free.first() {
            Some(src) => {
                if !src.as_path().exists() {
                    let path_str = String::from("\'".to_string() + src + "\'");
                    Status::ArgError.err(UTIL.name, path_str + " does not exist");
                } else if matches.free.len() == 1 {
                    println!("mv: No destination specified for '{}'", src);
                    Status::ArgError.exit();
                }
                for items in matches.free.split_first().unwrap().1.to_vec() {
                    rename(PathBuf::from(src), PathBuf::from(items));
                }
            }
            None => {
                UTIL.prog_try();
                Status::Error.exit();
            }
        };
    }
}