rapid 0.0.1

Rapid console application development
Documentation
use std::result::Result;
use docopt::{ArgvMap, Docopt, Error as DocoptError};
use serde::de::Deserialize;

type DocoptResult<T> = Result<T, DocoptError>;

pub enum ParsingResult<TCmdArgs> {
    Args(TCmdArgs),
    Version,
    Help,
    Error(DocoptError)
}

pub fn parse_cmd_args<'a, TCmdArgs>(usage: &str) -> ParsingResult<TCmdArgs>
    where TCmdArgs: Deserialize<'a>
{
    match parse_args(usage) {
        Ok(ref argv_map) if is_help(argv_map)    => ParsingResult::Help,
        Ok(ref argv_map) if is_version(argv_map) => ParsingResult::Version,
        Ok(argv_map)                             => deserialize_args(argv_map),
        Err(e)                                   => ParsingResult::Error(e),
    }
}

fn parse_args(usage: &str) -> DocoptResult<ArgvMap> {
    Docopt::new(usage)
        .map(|docopt| docopt
            .help(false)
            .version(None)
        )
        .and_then(|d| d.parse())
}

fn is_help(argv_map: &ArgvMap) -> bool {
    argv_map.get_bool("--help") || argv_map.get_bool("-h")
}

fn is_version(argv_map: &ArgvMap) -> bool {
    argv_map.get_bool("--version") || argv_map.get_bool("-v")
}

fn deserialize_args<'a, TCmdArgs>(argv_map: ArgvMap) -> ParsingResult<TCmdArgs>
    where TCmdArgs: Deserialize<'a>
{
    match argv_map.deserialize() {
        Ok(args) => ParsingResult::Args(args),
        Err(e)   => ParsingResult::Error(e)
    }
}