mirror of
https://github.com/jht5945/rust_util.git
synced 2025-12-27 15:40:03 +08:00
feat: v0.6.46
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rust_util"
|
name = "rust_util"
|
||||||
version = "0.6.45"
|
version = "0.6.46"
|
||||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Hatter's Rust Util"
|
description = "Hatter's Rust Util"
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ pub fn is_env_off(var: &str) -> bool {
|
|||||||
|
|
||||||
pub fn is_on(val: &str) -> bool {
|
pub fn is_on(val: &str) -> bool {
|
||||||
let lower_val = val.to_lowercase();
|
let lower_val = val.to_lowercase();
|
||||||
vec!["true", "yes", "1"].iter().any(|x| *x == lower_val)
|
["true", "yes", "1"].iter().any(|x| *x == lower_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_off(val: &str) -> bool {
|
pub fn is_off(val: &str) -> bool {
|
||||||
let lower_val = val.to_lowercase();
|
let lower_val = val.to_lowercase();
|
||||||
vec!["false", "no", "0"].iter().any(|x| *x == lower_val)
|
["false", "no", "0"].iter().any(|x| *x == lower_val)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub struct JoinFilesReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_file_as_lines(f: &str) -> XResult<Lines<BufReader<File>>> {
|
fn open_file_as_lines(f: &str) -> XResult<Lines<BufReader<File>>> {
|
||||||
let f = File::open(&f)?;
|
let f = File::open(f)?;
|
||||||
let br = BufReader::new(f);
|
let br = BufReader::new(f);
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
Ok(br.lines())
|
Ok(br.lines())
|
||||||
@@ -191,7 +191,7 @@ fn walk_dir_with_depth_check<FError, FProcess, FFilter>(depth: &mut u32, dir: &P
|
|||||||
let read_dir = match dir.read_dir() {
|
let read_dir = match dir.read_dir() {
|
||||||
Ok(rd) => rd,
|
Ok(rd) => rd,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
func_walk_error(&dir, Box::new(err));
|
func_walk_error(dir, Box::new(err));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -199,7 +199,7 @@ fn walk_dir_with_depth_check<FError, FProcess, FFilter>(depth: &mut u32, dir: &P
|
|||||||
let dir_entry = match dir_entry_item {
|
let dir_entry = match dir_entry_item {
|
||||||
Ok(item) => item,
|
Ok(item) => item,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
func_walk_error(&dir, Box::new(err));
|
func_walk_error(dir, Box::new(err));
|
||||||
continue; // Ok?
|
continue; // Ok?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -207,11 +207,11 @@ fn walk_dir_with_depth_check<FError, FProcess, FFilter>(depth: &mut u32, dir: &P
|
|||||||
let path_buf = dir_entry.path();
|
let path_buf = dir_entry.path();
|
||||||
let sub_dir = path_buf.as_path();
|
let sub_dir = path_buf.as_path();
|
||||||
if sub_dir.is_file() {
|
if sub_dir.is_file() {
|
||||||
func_process_file(&sub_dir);
|
func_process_file(sub_dir);
|
||||||
} else if sub_dir.is_dir() && func_filter_dir(&sub_dir) {
|
} else if sub_dir.is_dir() && func_filter_dir(sub_dir) {
|
||||||
*depth += 1;
|
*depth += 1;
|
||||||
if let Err(err) = walk_dir_with_depth_check(depth, &sub_dir, func_walk_error, func_process_file, func_filter_dir) {
|
if let Err(err) = walk_dir_with_depth_check(depth, sub_dir, func_walk_error, func_process_file, func_filter_dir) {
|
||||||
func_walk_error(&sub_dir, err);
|
func_walk_error(sub_dir, err);
|
||||||
}
|
}
|
||||||
*depth -= 1;
|
*depth -= 1;
|
||||||
} // should process else ? not file, dir
|
} // should process else ? not file, dir
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use crate::{XResult, util_msg, util_cmd};
|
|
||||||
|
use crate::{util_cmd, util_msg, XResult};
|
||||||
|
|
||||||
const LANG: &str = "LANG";
|
const LANG: &str = "LANG";
|
||||||
const EN_US: &str = "en_US";
|
const EN_US: &str = "en_US";
|
||||||
@@ -75,7 +76,7 @@ pub fn git_add(working_dir: Option<&str>, files: &[String]) {
|
|||||||
let mut cmd = new_git_command(working_dir);
|
let mut cmd = new_git_command(working_dir);
|
||||||
cmd.arg("add");
|
cmd.arg("add");
|
||||||
for f in files {
|
for f in files {
|
||||||
cmd.arg(&f);
|
cmd.arg(f);
|
||||||
}
|
}
|
||||||
util_msg::print_info(&format!("Exec: {:?}", cmd));
|
util_msg::print_info(&format!("Exec: {:?}", cmd));
|
||||||
if let Err(e) = util_cmd::run_command_and_wait(&mut cmd) {
|
if let Err(e) = util_cmd::run_command_and_wait(&mut cmd) {
|
||||||
@@ -89,7 +90,7 @@ pub fn git_commit(working_dir: Option<&str>, message: &str, files: &[String]) {
|
|||||||
cmd.arg("-m");
|
cmd.arg("-m");
|
||||||
cmd.arg(message);
|
cmd.arg(message);
|
||||||
for f in files {
|
for f in files {
|
||||||
cmd.arg(&f);
|
cmd.arg(f);
|
||||||
}
|
}
|
||||||
util_msg::print_info(&format!("Exec: {:?}", cmd));
|
util_msg::print_info(&format!("Exec: {:?}", cmd));
|
||||||
if let Err(e) = util_cmd::run_command_and_wait(&mut cmd) {
|
if let Err(e) = util_cmd::run_command_and_wait(&mut cmd) {
|
||||||
@@ -100,19 +101,19 @@ pub fn git_commit(working_dir: Option<&str>, message: &str, files: &[String]) {
|
|||||||
fn parse_git_status_change(git_status: &str) -> XResult<GitStatusChange> {
|
fn parse_git_status_change(git_status: &str) -> XResult<GitStatusChange> {
|
||||||
let mut git_status_change: GitStatusChange = Default::default();
|
let mut git_status_change: GitStatusChange = Default::default();
|
||||||
for ln in git_status.lines() {
|
for ln in git_status.lines() {
|
||||||
if ln.starts_with("\t") {
|
if ln.starts_with('\t') {
|
||||||
let ln = ln.trim();
|
let ln = ln.trim();
|
||||||
if ln.starts_with("new file:") {
|
if let Some(new_file) = ln.strip_prefix("new file:") {
|
||||||
let f = ln["new file:".len()..].trim();
|
let f = new_file.trim();
|
||||||
git_status_change.added.push(f.to_owned());
|
git_status_change.added.push(f.to_owned());
|
||||||
} else if ln.starts_with("deleted:") {
|
} else if let Some(deleted) = ln.strip_prefix("deleted:") {
|
||||||
let f = ln["deleted:".len()..].trim();
|
let f = deleted.trim();
|
||||||
git_status_change.deleted.push(f.to_owned());
|
git_status_change.deleted.push(f.to_owned());
|
||||||
} else if ln.starts_with("modified:") {
|
} else if let Some(modified) = ln.strip_prefix("modified:") {
|
||||||
let f = ln["modified:".len()..].trim();
|
let f = modified.trim();
|
||||||
git_status_change.modified.push(f.to_owned());
|
git_status_change.modified.push(f.to_owned());
|
||||||
} else if ln.starts_with("renamed:") {
|
} else if let Some(renamed) = ln.strip_prefix("renamed:") {
|
||||||
let f = ln["renamed:".len()..].trim();
|
let f = renamed.trim();
|
||||||
let mut fs = f.split("->");
|
let mut fs = f.split("->");
|
||||||
let fa = fs.next();
|
let fa = fs.next();
|
||||||
let fb = fs.next();
|
let fb = fs.next();
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use std::io::{self, Write, ErrorKind, prelude::*};
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::time::{SystemTime, Duration};
|
use std::io::{self, ErrorKind, prelude::*, Write};
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use crate::{SimpleError, XResult};
|
use crate::{SimpleError, XResult};
|
||||||
use crate::util_size;
|
|
||||||
use crate::util_msg;
|
|
||||||
use crate::util_file;
|
use crate::util_file;
|
||||||
|
use crate::util_msg;
|
||||||
|
use crate::util_size;
|
||||||
|
|
||||||
pub const DEFAULT_BUF_SIZE: usize = 8 * 1024;
|
pub const DEFAULT_BUF_SIZE: usize = 8 * 1024;
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ pub fn get_read_stdin_or_file(file: &str) -> XResult<Box<dyn Read>> {
|
|||||||
if file.is_empty() {
|
if file.is_empty() {
|
||||||
Ok(Box::new(io::stdin()))
|
Ok(Box::new(io::stdin()))
|
||||||
} else {
|
} else {
|
||||||
match File::open(&util_file::resolve_file_path(file)) {
|
match File::open(util_file::resolve_file_path(file)) {
|
||||||
Ok(f) => Ok(Box::new(f)),
|
Ok(f) => Ok(Box::new(f)),
|
||||||
Err(err) => Err(SimpleError::new(format!("Open file {}, erorr: {}", file, err)).into()),
|
Err(err) => Err(SimpleError::new(format!("Open file {}, erorr: {}", file, err)).into()),
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@ pub fn print_status_last_line(head: &str, total: i64, written: i64, print_status
|
|||||||
}
|
}
|
||||||
let cost_as_secs = cost.as_secs();
|
let cost_as_secs = cost.as_secs();
|
||||||
if cost_as_secs > 0 {
|
if cost_as_secs > 0 {
|
||||||
download_speed = format!("{}/s", util_size::get_display_size((written / (cost_as_secs as i64)) as i64));
|
download_speed = format!("{}/s", util_size::get_display_size(written / (cost_as_secs as i64)));
|
||||||
}
|
}
|
||||||
if total > 0 {
|
if total > 0 {
|
||||||
util_msg::print_lastline(&format!("{}, Total: {}, Finished: {}, Speed: {}",
|
util_msg::print_lastline(&format!("{}, Total: {}, Finished: {}, Speed: {}",
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ pub fn get_logger_level() -> MessageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_atty() -> bool {
|
pub fn is_atty() -> bool {
|
||||||
let stdout_fileno = unsafe { libc::isatty(libc::STDOUT_FILENO as i32) };
|
let stdout_fileno = unsafe { libc::isatty(libc::STDOUT_FILENO) };
|
||||||
stdout_fileno != 0
|
stdout_fileno != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +124,7 @@ pub fn print_ex(message: &str, new_line: bool) {
|
|||||||
print!("{}", message)
|
print!("{}", message)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#[allow(clippy::collapsible_else_if)]
|
||||||
if new_line {
|
if new_line {
|
||||||
eprintln!("{}", message)
|
eprintln!("{}", message)
|
||||||
} else {
|
} else {
|
||||||
@@ -148,6 +149,10 @@ pub fn is_logger_level_enabled(mt: MessageType) -> bool {
|
|||||||
mt.get_u8_value() >= logger_level.get_u8_value()
|
mt.get_u8_value() >= logger_level.get_u8_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn when_debug<F>(f: F) where F: Fn() {
|
||||||
|
when(MessageType::DEBUG, f)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn when<F>(mt: MessageType, f: F) where F: Fn() {
|
pub fn when<F>(mt: MessageType, f: F) where F: Fn() {
|
||||||
if is_logger_level_enabled(mt) {
|
if is_logger_level_enabled(mt) {
|
||||||
f();
|
f();
|
||||||
@@ -206,9 +211,9 @@ pub fn get_term_width_message(message: &str, left: usize) -> String {
|
|||||||
return message.to_string();
|
return message.to_string();
|
||||||
}
|
}
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
s.push_str(&message[0..find_char_boundary(&message, w - 10 - 5 - left)]);
|
s.push_str(&message[0..find_char_boundary(message, w - 10 - 5 - left)]);
|
||||||
s.push_str("[...]");
|
s.push_str("[...]");
|
||||||
s.push_str(&message[find_char_boundary(&message, len - 10)..]);
|
s.push_str(&message[find_char_boundary(message, len - 10)..]);
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ pub struct IpAndIpMaskMatcher {
|
|||||||
ip_and_ip_mask_set: HashSet<u64>,
|
ip_and_ip_mask_set: HashSet<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for IpAndIpMaskMatcher {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IpAndIpMaskMatcher {
|
impl IpAndIpMaskMatcher {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
IpAndIpMaskMatcher {
|
IpAndIpMaskMatcher {
|
||||||
@@ -133,7 +139,7 @@ impl IpAddressMask {
|
|||||||
let socket_addr_v4_octets = socket_addr_v4.ip().octets();
|
let socket_addr_v4_octets = socket_addr_v4.ip().octets();
|
||||||
match self {
|
match self {
|
||||||
IpAddressMask::Ipv4(self_ipv4_octets, mask) => {
|
IpAddressMask::Ipv4(self_ipv4_octets, mask) => {
|
||||||
let self_ipv4_u32 = ipv4_to_u32(&self_ipv4_octets);
|
let self_ipv4_u32 = ipv4_to_u32(self_ipv4_octets);
|
||||||
let addr_ipv4_u32 = ipv4_to_u32(&socket_addr_v4_octets);
|
let addr_ipv4_u32 = ipv4_to_u32(&socket_addr_v4_octets);
|
||||||
let mask_u32 = ipv4_mask(*mask);
|
let mask_u32 = ipv4_mask(*mask);
|
||||||
self_ipv4_u32 & mask_u32 == addr_ipv4_u32 & mask_u32
|
self_ipv4_u32 & mask_u32 == addr_ipv4_u32 & mask_u32
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::iff;
|
use crate::iff;
|
||||||
|
|
||||||
pub fn is_macos() -> bool {
|
pub fn is_macos() -> bool {
|
||||||
@@ -19,7 +20,7 @@ pub fn get_user_home() -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_full_work_dir() -> Option<String> {
|
pub fn get_full_work_dir() -> Option<String> {
|
||||||
PathBuf::from(".").canonicalize().ok().map(|p| {
|
PathBuf::from(".").canonicalize().ok().and_then(|p| {
|
||||||
p.to_str().map(ToString::to_string)
|
p.to_str().map(ToString::to_string)
|
||||||
}).flatten()
|
})
|
||||||
}
|
}
|
||||||
@@ -16,10 +16,10 @@ pub fn read_yes_no(hint: &str) -> bool {
|
|||||||
let mut buff = String::new();
|
let mut buff = String::new();
|
||||||
let _ = io::stdin().read_line(&mut buff).expect("Read line from stdin");
|
let _ = io::stdin().read_line(&mut buff).expect("Read line from stdin");
|
||||||
let buff = buff.trim().to_lowercase();
|
let buff = buff.trim().to_lowercase();
|
||||||
if vec!["y", "yes"].contains(&buff.as_str()) {
|
if ["y", "yes"].contains(&buff.as_str()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if vec!["n", "no"].contains(&buff.as_str()) {
|
if ["n", "no"].contains(&buff.as_str()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user