feat: first commit (with new, default)

This commit is contained in:
2020-07-25 21:01:37 +08:00
parent 34a7cb4936
commit 08fa747430
8 changed files with 1467 additions and 4 deletions

12
src/cmd.rs Normal file
View File

@@ -0,0 +1,12 @@
use clap::{ ArgMatches, App, };
pub type CommandError = Result<(), Box<dyn std::error::Error>>;
pub trait Command {
fn name(&self) -> &str;
fn subcommand<'a>(&self) -> App<'a, 'a>;
fn run(&self, arg_matches: &ArgMatches, _: &ArgMatches) -> CommandError;
}

19
src/cmd_default.rs Normal file
View File

@@ -0,0 +1,19 @@
use clap::{ App, Arg, ArgMatches, };
use crate::cmd::CommandError;
pub struct CommandDefault;
impl CommandDefault {
pub fn process_command<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
app.arg(Arg::with_name("verbose").long("verbose").short("v").multiple(true).help("Show verbose info"))
}
pub fn run(arg_matches: &ArgMatches) -> CommandError {
let verbose_count = arg_matches.occurrences_of("verbose");
println!("Verbose count: {}", verbose_count);
error!("Default command is not implemented!");
Ok(())
}
}

35
src/cmd_new.rs Normal file
View File

@@ -0,0 +1,35 @@
use std::fs;
use std::fs::File;
use std::os::unix::fs::PermissionsExt;
use clap::{ Arg, ArgMatches, SubCommand, App };
use crate::{ success, warning };
use crate::cmd::{ Command, CommandError };
const CRS_TEMPLATE: &[u8] = include_bytes!("../crs_template.txt");
pub struct CommandNew;
impl Command for CommandNew {
fn name(&self) -> &str { "new" }
fn subcommand<'a>(&self) -> App<'a, 'a> {
SubCommand::with_name(self.name()).about("New script subcommand")
.arg(Arg::with_name("FILE_NAME").required(true).help("Script file name"))
}
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
let file_name = sub_arg_matches.value_of("FILE_NAME").unwrap();
if File::open(&file_name).is_ok() {
error!("File exists: {}", file_name);
return Ok(());
}
if !file_name.ends_with(".crs") {
warning!("File is not ends with .crs");
}
fs::write(&file_name, CRS_TEMPLATE)?;
fs::set_permissions(&file_name, PermissionsExt::from_mode(0o755))?;
success!("Success, written file: {}", file_name);
Ok(())
}
}

54
src/main.rs Normal file
View File

@@ -0,0 +1,54 @@
#[macro_use] extern crate log;
//#[macro_use] extern crate lazy_static;
use clap::App;
mod cmd;
mod cmd_default;
mod cmd_new;
use cmd::{ Command, CommandError };
use cmd_default::CommandDefault;
use cmd_new::CommandNew;
#[macro_export] macro_rules! success {
($($arg:tt)+) => ( crate::print_ok(&format!($($arg)+)); )
}
#[macro_export] macro_rules! warning {
($($arg:tt)+) => ( crate::print_wa(&format!($($arg)+)); )
}
#[inline]
fn print_ok (msg: &str) {
println!("{g}{b}[ OK ]{e} {g}{m}{e}", g = "\x1B[92m", b = "\x1B[1m", e = "\x1B[0m", m = msg);
}
#[inline]
fn print_wa (msg: &str) {
println!("{g}{b}[WARN]{e} {g}{m}{e}", g = "\x1B[93m", b = "\x1B[1m", e = "\x1B[0m", m = msg);
}
fn main() -> CommandError {
pretty_env_logger::init();
info!("rust-script-tool started");
let commands: Vec<Box<dyn Command>> = vec![
Box::new(CommandNew{}),
];
let mut app = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"));
app = CommandDefault::process_command(app);
for command in &commands {
app = app.subcommand(command.subcommand());
}
let matches = app.get_matches();
for command in &commands {
if let Some(sub_cmd_matches) = matches.subcommand_matches(command.name()) {
info!("matched subcommand: {}", command.name());
return command.run(&matches, sub_cmd_matches);
}
}
info!("matched default subcommand");
CommandDefault::run(&matches)
}