e9571_lib1 0.1.2

A Rust crate providing utilities for time formatting, HTTP requests, string parsing, and more
Documentation
use std::time::{SystemTime, UNIX_EPOCH, Duration};
use chrono::{DateTime, Local};
use rand::{rng, Rng};
use reqwest::blocking::Client;
use regex::Regex;
use md5;
use std::path::Path;
use std::env;
use local_ip_address::local_ip;

pub mod e9571_lib1 {
    use super::*;

    /// Generate a high-precision random user ID
    pub fn high_rand_user(prefix: &str) -> String {
        let now = SystemTime::now();
        let timestamp = now.duration_since(UNIX_EPOCH).unwrap().as_secs();
        let rand_num = rng().random_range(1_000_000..=9_999_999);
        format!("{}_{}_{}", prefix, timestamp, rand_num)
    }

    /// Ultra-simplified HTTP GET request
    pub fn get_http(url_str: &str) -> Result<String, Box<dyn std::error::Error>> {
        let client = Client::builder()
            .timeout(Duration::from_secs(30))
            .build()?;
        let resp = client.get(url_str).send()?;
        let body = resp.text()?;
        Ok(body)
    }

    /// HTTP GET request with timeout and logging
    pub fn get_http_wait(url_str: &str, wait: u64, show: i32) -> Result<String, Box<dyn std::error::Error>> {
        if show == 1 {
            let now: DateTime<Local> = DateTime::from(SystemTime::now());
            println!("{} open http {} wait {}", now.format("%Y-%m-%d %H:%M:%S"), url_str, wait);
        }
        let client = Client::builder()
            .timeout(Duration::from_secs(wait))
            .build()?;
        let resp = client.get(url_str).send()?;
        let body = resp.text()?;
        println!("{} body {}", now().format("%Y-%m-%d %H:%M:%S"), body.len());
        Ok(body)
    }

    /// Helper function: Get current time
    fn now() -> DateTime<Local> {
        DateTime::from(SystemTime::now())
    }

    /// Convert string to int
    pub fn parse_int(value: &str) -> i32 {
        value.parse::<i32>().unwrap_or(-1)
    }

    /// Convert string to int8
    pub fn parse_int8(value: &str) -> i8 {
        value.parse::<i8>().unwrap_or(-1)
    }

    /// Convert string to uint8
    pub fn parse_uint8(value: &str) -> u8 {
        value.parse::<u8>().unwrap_or(0)
    }

    /// Convert string to int64
    pub fn parse_int64(value: &str) -> i64 {
        value.parse::<i64>().unwrap_or(-1)
    }

    /// Convert string to uint64
    pub fn parse_uint64(value: &str) -> u64 {
        value.parse::<u64>().unwrap_or(0)
    }

    /// Convert string to float64
    pub fn parse_float(value: &str) -> f64 {
        value.parse::<f64>().unwrap_or(-1.0)
    }

    /// Extract all matches using regular expression
    pub fn get_data_preg_list(parameter: &str, source: &str) -> Vec<String> {
        let re = Regex::new(parameter).unwrap();
        re.find_iter(source)
            .map(|m| m.as_str().to_string())
            .collect()
    }

    /// Extract the first string containing the specified pattern from regex results
    pub fn get_data_preg_str(parameter: Vec<String>, sign: &str) -> String {
        for value in parameter {
            if value.contains(sign) {
                return value;
            }
        }
        String::new()
    }

    /// Dynamically match integers or floating-point numbers
    pub fn create_number(source: &str) -> String {
        let int_regex = Regex::new(r"[+-]?\d+").unwrap();
        let results = get_data_preg_list(r"[+-]?\d+", source);
        if results.is_empty() {
            return String::new();
        }
        if results.len() > 1 {
            let float_regex = Regex::new(r"[+-]?\d+\.\d+").unwrap();
            let float_results = get_data_preg_list(r"[+-]?\d+\.\d+", source);
            if !float_results.is_empty() {
                return float_results[0].clone();
            }
        }
        results[0].clone()
    }

    /// Extract all letters and digits (Bitcoin address)
    pub fn get_data_preg_address(parameter: &str) -> String {
        let regex = Regex::new(r"[A-Za-z\d]+").unwrap();
        let results = get_data_preg_list(r"[A-Za-z\d]+", parameter);
        results.join("")
    }

    /// Extract only letters
    pub fn get_data_preg_address_letter(parameter: &str) -> String {
        let regex = Regex::new(r"[A-Za-z]+").unwrap();
        let results = get_data_preg_list(r"[A-Za-z]+", parameter);
        results.get(0).cloned().unwrap_or_default()
    }

    /// Super positioning: Extract a string of specified length after regex match
    pub fn get_data_preg_search_str(parameter: &str, regexp_str: &str, sign: &str, number: usize) -> String {
        let results = get_data_preg_list(regexp_str, parameter);
        let value = get_data_preg_str(results, sign);
        value.chars().take(number).collect()
    }

    /// Sort map keys
    pub fn taxis_map(m: std::collections::HashMap<String, String>) -> Vec<String> {
        let mut sorted_keys: Vec<String> = m.keys().cloned().collect();
        sorted_keys.sort();
        sorted_keys
    }

    /// Format error
    pub fn sprintf_err_write(str: &str) -> Box<dyn std::error::Error> {
        Box::<dyn std::error::Error>::from(str.to_string())
    }

    /// Format error message
    pub fn sprintf_err_msg(err: Option<&dyn std::error::Error>) -> String {
        match err {
            Some(e) => e.to_string(),
            None => String::new(),
        }
    }

    /// MD5 encryption (uppercase)
    pub fn default_encode_md5(data_source: &str) -> String {
        let digest = md5::compute(data_source);
        format!("{:X}", digest)
    }

    /// String tokenization
    pub fn word_split(data_source: &str, data_sign: &str) -> Vec<String> {
        data_source.split(data_sign).map(|s| s.to_string()).collect()
    }

    /// SQL injection filtering
    pub fn sql_filtrate(str: &str) -> String {
        let mut result = str.to_string();
        result = result.replace("'", "\\'");
        result = result.replace("#", "\\#");
        result = result.replace("--", "\\--");
        result = result.replace("\\*", "\\\\*");
        result.replace("*/", "\\*/");
        result.replace(" ", "")
    }

    /// SQL injection filtering (keep only letters and digits)
    pub fn sql_filtrate_str(parameter: &str) -> String {
        get_data_preg_address(parameter)
    }

    /// Check if string is in array
    pub fn in_array(array_list: &[String], value: &str) -> bool {
        array_list.iter().any(|x| x == value)
    }

    pub fn in_array_int(array_list: &[i32], value: i32) -> bool {
        array_list.iter().any(|&x| x == value)
    }

    pub fn in_array_int64(array_list: &[i64], value: i64) -> bool {
        array_list.iter().any(|&x| x == value)
    }

    pub fn in_array_float(array_list: &[f64], value: f64) -> bool {
        array_list.iter().any(|&x| x == value)
    }

    /// Number formatting
    pub fn conversion_num(number: f64, number_place: i32) -> String {
        format!("{:.*}", number_place as usize, number)
    }

    /// Get local IP
    pub fn create_ip() -> String {
        match local_ip() {
            Ok(ip) => ip.to_string(),
            Err(_) => "0".to_string(),
        }
    }

    /// Get startup arguments
    pub fn create_args() -> Vec<String> {
        let args: Vec<String> = env::args().collect();
        for (idx, arg) in args.iter().enumerate() {
            println!("Startup argument {}: {}", idx, arg);
        }
        args
    }

    /// Get program filename (without extension)
    pub fn create_exe_name() -> String {
        let exe_path = env::args().next().unwrap_or_default();
        let path = Path::new(&exe_path);
        path.file_stem()
            .and_then(|s| s.to_str())
            .unwrap_or_default()
            .to_string()
    }

    /// Get executable file path
    pub fn create_path_os() -> Result<String, Box<dyn std::error::Error>> {
        let ex = std::env::current_exe()?;
        let ex_path = ex.parent()
            .and_then(|p| p.to_str())
            .map(|s| s.to_string())
            .ok_or_else(|| Box::<dyn std::error::Error>::from("Failed to get path"))?;
        Ok(ex_path)
    }
}