1
0
mirror of https://github.com/jht5945/rust_util.git synced 2025-12-27 07:30:05 +08:00

feat: add runtime

This commit is contained in:
2021-05-30 01:01:56 +08:00
parent 53720edc00
commit c8a0f22425
6 changed files with 65 additions and 17 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "rust_util"
version = "0.6.35"
version = "0.6.36"
authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018"
description = "Hatter's Rust Util"

View File

@@ -20,6 +20,7 @@ pub mod util_git;
#[cfg(feature = "use_clap")]
pub mod util_clap;
pub mod util_tlv;
pub mod util_runtime;
/// iff!(condition, result_when_true, result_when_false)
#[macro_export] macro_rules! iff {
@@ -47,6 +48,7 @@ pub mod util_tlv;
#[macro_export] macro_rules! failure_and_exit {
($($arg:tt)+) => ( {
rust_util::util_msg::print_error(&format!($($arg)+));
rsut_util::util_runtime::register_callback();
std::process::exit(-1);
} )
}

View File

@@ -16,6 +16,7 @@ pub trait DefaultCommand {
}
pub struct DefaultCommandImpl;
impl DefaultCommand for DefaultCommandImpl {
fn process_command<'a>(&self, app: App<'a, 'a>) -> App<'a, 'a> {
app.arg(Arg::with_name("verbose").long("verbose").short("v").multiple(true).help("Show verbose info"))
@@ -40,7 +41,7 @@ impl CommandExecutor {
}
pub fn new(default_cmd: Option<Box<dyn DefaultCommand>>) -> Self {
CommandExecutor{
CommandExecutor {
default_cmd,
commands: Vec::new(),
}
@@ -60,8 +61,8 @@ impl CommandExecutor {
pub fn run(&self) -> XResult<()> {
let app = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"));
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"));
self.run_with(app)
}
@@ -77,18 +78,25 @@ impl CommandExecutor {
if let Some(sub_cmd_matches) = matches.subcommand_matches(command.name()) {
match command.run(&matches, sub_cmd_matches)? {
None => return Ok(()),
Some(code) => process::exit(code),
Some(code) => {
crate::util_runtime::invoke_callbacks();
process::exit(code);
}
}
}
}
match &self.default_cmd {
None => {
util_msg::print_error("No default command, please try help (--help)");
crate::util_runtime::invoke_callbacks();
process::exit(1);
},
}
Some(default_cmd) => match default_cmd.run(&matches)? {
None => return Ok(()),
Some(code) => process::exit(code),
Some(code) => {
crate::util_runtime::invoke_callbacks();
process::exit(code);
}
},
}
}

View File

@@ -1,6 +1,6 @@
use std::io::{self, Error, ErrorKind};
use std::process::{Command, ExitStatus, Output};
use crate::util_msg::{print_debug, print_error, MessageType};
use crate::util_msg::{print_debug, print_error, MessageType, print_message};
pub fn run_command_or_exit(cmd: &str, args: &[&str]) -> Output {
let mut c = Command::new(cmd);
@@ -12,23 +12,30 @@ pub fn run_command_or_exit(cmd: &str, args: &[&str]) -> Output {
match output {
Err(e) => {
print_error(&format!("Run command: {:?}, failed: {}", c, e));
crate::util_runtime::invoke_callbacks();
std::process::exit(-1);
},
}
Ok(output) => {
if !output.status.success() {
print_error(&format!(r##"Run command failed, code: {:?}
print_output(MessageType::ERROR, &output);
}
output
}
}
}
pub fn print_output(message_type: MessageType, output: &Output) {
crate::util_msg::when(message_type, || {
print_message(message_type, &format!(r##"Run command failed, code: {:?}
-----std out---------------------------------------------------------------
{}
-----std err---------------------------------------------------------------
{}
---------------------------------------------------------------------------"##,
output.status.code(),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)));
}
output
}
}
output.status.code(),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)));
});
}
pub fn run_command_and_wait(cmd: &mut Command) -> io::Result<ExitStatus> {

View File

@@ -1,3 +1,4 @@
use std::path::PathBuf;
pub fn is_macos() -> bool {
cfg!(target_os = "macos")
@@ -10,3 +11,9 @@ pub fn is_linux() -> bool {
pub fn is_macos_or_linux() -> bool {
is_macos() || is_linux()
}
pub fn get_full_work_dir() -> Option<String> {
PathBuf::from(".").canonicalize().ok().map(|p| {
p.to_str().map(ToString::to_string)
}).flatten()
}

24
src/util_runtime.rs Normal file
View File

@@ -0,0 +1,24 @@
use std::sync::Mutex;
use crate::util_msg::MessageType;
lazy_static! {
static ref EXIT_CALLBACK: Mutex<Vec<Box<dyn Fn() -> () + Send + 'static>>> = Mutex::new(vec![]);
}
pub fn register_callback<F>(f: F) where F: Fn() -> () + Send + 'static {
let mut exit_callbacks = EXIT_CALLBACK.lock().unwrap();
exit_callbacks.push(Box::new(f));
}
pub fn invoke_callbacks() {
let mut exit_callbacks = EXIT_CALLBACK.lock().unwrap();
let total = exit_callbacks.len();
let mut index = 0;
while exit_callbacks.len() > 0 {
crate::util_msg::when(MessageType::DEBUG, || {
crate::util_msg::print_debug(&format!("Running exit callbacks: {} of {}", index, total));
});
exit_callbacks.remove(0)();
index += 1;
}
}