///all macros
#[allow(warnings)]
#[macro_use]
pub mod macros {
    ///
    // Result<(), Box<dyn std::error::Error>>
    #[macro_export]
    macro_rules! dyn_error {
        () => {Result<(), Box<dyn std::error::Error>>};
    }

    #[macro_export]
    macro_rules! include_string {
        ($path:expr) => {
            include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path)).to_string()
        };
    }
    ///
    /// ```ignore
    /// use doe::run_time;
    /// run_time!{
    ///     {
    ///         for i in 0..10000{
    ///             println!("{}",i);
    ///         }
    ///     }
    /// };
    /// ```
    /// 
    #[macro_export]
    macro_rules! run_time {
        ($v:block) => {{
            use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
            use std::time::Instant;
            static ELAPSED_TIME_NS: AtomicUsize = AtomicUsize::new(0);
            let start = Instant::now();
            let _ret = $v;
            ELAPSED_TIME_NS.fetch_add(start.elapsed().as_nanos() as usize, SeqCst);
            println!("{}ms", ELAPSED_TIME_NS.load(SeqCst) / 1000 / 1000);
        }};
    }

    ///socketaddr
    /// ```
    /// use doe::socketaddr;
    /// let addr = socketaddr!("127.0.0.1", "8080");
    /// let addr = socketaddr!("127.0.0.1:8080");
    /// ```
    #[macro_export]
    macro_rules! socketaddr {
        ($ip:expr, $port:expr) => {{
            use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs};
            format!("{}:{}", $ip, $port)
                .to_socket_addrs()
                .unwrap()
                .next()
                .unwrap()
        }};
        ($str:expr) => {{
            use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs};
            $str.to_socket_addrs().unwrap().next().unwrap()
        }};
    }
    ///## like pythons os.system() function
    #[cfg(target_os = "linux")]
    #[macro_export]
    macro_rules! system {
        ( $a:expr) => {{
            pub fn system(command: impl ToString) -> std::io::Result<()> {
                use std::process::Command;
                Command::new("sh")
                    .arg("-c")
                    .arg(&command.to_string())
                    .status()
                    .map(|_| ())
            }
            system($a).unwrap()
        }};
    }
    ///## like pythons os.system() function
    #[cfg(target_os = "macos")]
    #[macro_export]
    macro_rules! system {
        ( $a:expr) => {{
            pub fn system(command: impl ToString) -> std::io::Result<()> {
                use std::process::Command;
                Command::new("sh")
                    .arg("-c")
                    .arg(&command.to_string())
                    .status()
                    .map(|_| ())
            }
            system($a).unwrap()
        }};
    }
    ///## like pythons os.system() function
    #[cfg(target_os = "windows")]
    #[macro_export]
    macro_rules! system_cmd {
        ( $a:expr) => {{
            pub fn system(command: impl ToString) -> std::io::Result<()> {
                use std::process::Command;
                Command::new("cmd")
                    .arg("/c")
                    .arg(&command.to_string())
                    .status()
                    .map(|_| ())
            }
            system($a).unwrap()
        }};
    }
    ///## like pythons os.system() function
    #[cfg(target_os = "windows")]
    #[macro_export]
    macro_rules! system {
        ( $a:expr) => {{
            pub fn system(command: impl ToString) -> std::io::Result<()> {
                use std::process::Command;
                Command::new("powershell")
                    .arg("-Command")
                    .arg(&command.to_string())
                    .status()
                    .map(|_| ())
            }
            system($a).unwrap()
        }};
    }
    ///## convert type
    /// ```rust
    ///  use doe::*;
    ///  let s = as_to!(5., i64);
    ///  assert_eq!(5, s);
    /// ```
    #[macro_export]
    macro_rules! as_to {
        ( $a:expr,$type:ty ) => {
            ($a as $type)
        };
    }
    use std::{
        any::Any,
        collections::HashMap,
        fmt::{Debug, Display},
    };
    ///##  if type is i8 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_i8(&5_i8),true);
    /// ```
    pub fn is_i8(s: &dyn Any) -> bool {
        if s.is::<i8>() {
            return true;
        } else {
            return false;
        }
    }
    ///##  if type is i16 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_i16(&5_i16),true);
    /// ```
    pub fn is_i16(s: &dyn Any) -> bool {
        if s.is::<i16>() {
            return true;
        } else {
            return false;
        }
    }
    ///##  if type is i32 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_i32(&5_i32),true);
    /// ```
    pub fn is_i32(s: &dyn Any) -> bool {
        if s.is::<i32>() {
            return true;
        } else {
            return false;
        }
    }
    ///##  if type is i64 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_i64(&5_i64),true);
    /// ```
    pub fn is_i64(s: &dyn Any) -> bool {
        if s.is::<i64>() {
            return true;
        } else {
            return false;
        }
    }
    ///##  if type is i128 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_i128(&5_i128),true);
    /// ```
    pub fn is_i128(s: &dyn Any) -> bool {
        if s.is::<i128>() {
            return true;
        } else {
            return false;
        }
    }
    ///##  if type is f32 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_f32(&5.0_f32),true);
    /// ```
    pub fn is_f32(s: &dyn Any) -> bool {
        if s.is::<f32>() {
            return true;
        } else {
            return false;
        }
    }
    ///##  if type is f64 return true
    /// ```rust
    /// use doe::*;
    /// assert_eq!(is_f64(&5.0_f64),true);
    /// ```
    pub fn is_f64(s: &dyn Any) -> bool {
        if s.is::<f64>() {
            return true;
        } else {
            return false;
        }
    }

    pub fn pow<T>(a: T, b: T) -> T
    where
        f64: From<T>,
        T: 'static
            + std::ops::MulAssign
            + std::fmt::Display
            + std::ops::Mul<Output = T>
            + Copy
            + std::convert::From<f64>,
    {
        let mut re = a;
        let aa: f64 = a.into();
        let bb: f64 = b.into();
        re = f64::powf(aa, bb).into();
        re
    }
    ///## returns a raised to the b power
    /// ```rust
    /// use doe::*;
    /// let p = powf!(2.,2.);
    /// assert_eq!(p,4.0);
    /// ```
    #[macro_export]
    macro_rules! powf {
        ($a:expr,$b:expr) => {
            f64::powf($a, $b)
        };
    }
    ///## get argument and collect into Vec\<String\>
    /// ```ignore
    /// use doe::*;
    /// //cargo run -- -n 100
    /// let arg = args!();
    /// assert_eq!(arg,vec![format!("-n"),format!("100")]);
    /// ```
    #[macro_export]
    macro_rules! args {
        () => {
            std::env::args().skip(1).collect::<Vec<String>>()
        };
    }
    ///## get user input from terminal,return String
    /// ```rust
    /// use doe::*;
    /// let s = input!();
    /// println!("{:?}",s);
    /// ```
    #[macro_export]
    macro_rules! input {
        () => {{
            let mut string = String::new();
            std::io::stdin().read_line(&mut string).unwrap();
            string = string.to_string().trim().to_owned();
            string
        }};

        ($prompt:expr) => {{
            print!("{}", $prompt);
            use std::io::Write;
            // flush stdout buffer to ensure prompt is printed before reading input
            std::io::stdout().flush().unwrap();
            let mut string = String::new();
            std::io::stdin().read_line(&mut string).unwrap();
            string = string.trim().to_owned();
            string
        }};
    }
    #[macro_export]
    macro_rules! input_lines {
        () => {{
            use std::io::{self, BufRead};
            let stdin = io::stdin();
            let lock = stdin.lock();
            let mut lines = lock.lines();

            let mut input_lines: Vec<String> = Vec::new();

            loop {
                if let Some(Ok(line)) = lines.next() {
                    if line.is_empty() {
                        break;
                    }
                    input_lines.push(line);
                } else {
                    break;
                }
            }
            input_lines
        }};

        ($prompt:expr) => {{
            print!("{}", $prompt);
            use std::io::Write;
            // flush stdout buffer to ensure prompt is printed before reading input
            std::io::stdout().flush().unwrap();
            use std::io::{self, BufRead};
            let stdin = io::stdin();
            let lock = stdin.lock();
            let mut lines = lock.lines();

            let mut input_lines: Vec<String> = Vec::new();

            loop {
                if let Some(Ok(line)) = lines.next() {
                    if line.is_empty() {
                        break;
                    }
                    input_lines.push(line);
                } else {
                    break;
                }
            }
            input_lines
        }};
    }
    ///## Spliy &str by spliter and collect into Vec\<String\>
    /// ```rust
    /// use doe::*;
    /// let s = split_to_vec!("aa.bb",".");
    /// assert_eq!(s,vec![format!("aa"),format!("bb")]);
    /// ```
    #[macro_export]
    macro_rules! split_to_vec {
        ($a:expr,$b:expr) => {
            $a.to_string()
                .split($b)
                .map(|s| s.to_string().trim().to_owned())
                .collect::<Vec<String>>()
        };
    }
    ///## read .csv file and Collect into Vec\<Vec\<String\>\>
    /// ```rust
    /// use doe::*;
    ///let s = read_csv!("./data.csv");
    ///assert_eq!(s,vec![vec![format!("a"), format!("b"), format!("c")],vec![format!("1"), format!("2"), format!("3")],vec![format!("10"), format!("20"), format!("30")]]);
    /// ```
    #[macro_export]
    macro_rules! read_csv {
        ($path:expr) => {{
            let data = std::fs::read($path).unwrap();
            use $crate::Str;
            let data_vec = String::from_utf8_lossy(&data).split_to_vec("\n");
            data_vec
                .iter()
                .map(|s| s.split_to_vec(","))
                .collect::<Vec<Vec<String>>>()
        }};
    }
    ///## sorted new Vec
    /// ```rust
    /// use doe::*;
    /// let s1 = sorted!(vec![1.2, 2.6, 0.2]);
    /// let s2 = sorted!(vec![8, 1_i128, 5_i128]);
    /// assert_eq!(s1,vec![0.2,1.2,2.6]);
    /// assert_eq!(s2,vec![1,5,8]);
    /// ```
    #[macro_export]
    macro_rules! sorted {
        ($vec:expr) => {{
            let mut vec = $vec.clone();
            vec.sort_by(|a, b| a.partial_cmp(b).unwrap());
            vec
        }};
    }
    ///## sorted and deduped Vec
    /// ```rust
    /// use doe::*;
    /// let s1 = deduped_sorted!(vec![1.2, 1.2,2.6, 0.2]);
    /// let s2 = deduped_sorted!(vec![8, 1_i128,8,5_i128]);
    /// assert_eq!(s1,vec![0.2,1.2,2.6]);
    /// assert_eq!(s2,vec![1,5,8]);
    /// ```
    #[macro_export]
    macro_rules! deduped_sorted {
        ($vec:expr) => {{
            let mut vec1 = $vec.clone();
            let mut vec2 = $crate::sorted!(vec1);
            vec2.dedup();
            vec2
        }};
    }
    ///## parse Vec element to type, parse Vec\<&str\> Collect to Vec\<type\>
    /// ```rust
    /// use doe::*;
    ///let v1: Vec<f64> = vec_element_parse!(vec!["15.", "2.9"], f64);
    ///let v2: Vec<i128> = vec_element_parse!(vec!["15", "2"], i128);
    ///let v3: Vec<f32> = vec_element_parse!(vec![".15", ".2"], f32);
    ///assert_eq!(vec![15.0, 2.9], v1);
    ///assert_eq!(vec![15, 2], v2);
    ///assert_eq!(vec![0.15, 0.2], v3);
    /// ```
    #[macro_export]
    macro_rules! vec_element_parse {
        ($vec:expr,$type:ty) => {{
            let mut v2: Vec<$type> = Vec::new();
            let vec = $vec.clone();
            if $vec.len() > 0 {
                match vec.get(0).unwrap().to_owned().parse::<$type>() {
                    Ok(_r) => {
                        let vec1 = $vec.clone();
                        v2 = vec1
                            .iter()
                            .map(|x| x.to_string().parse::<$type>().unwrap())
                            .collect::<Vec<_>>();
                    }
                    Err(_e) => {}
                }
            }
            v2
        }};
    }
    ///## convert vec item to String,return Vec\<String\>
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_element_to_string!(vec!["15.", "2.9"]);
    ///let v2 = vec_element_to_string!(vec![15, 2]);
    ///let v3 = vec_element_to_string!(vec![0.15, 0.2]);
    ///assert_eq!(vec!["15.", "2.9"], v1);
    ///assert_eq!(vec!["15", "2"], v2);
    ///assert_eq!(vec!["0.15", "0.2"], v3);
    /// ```
    #[macro_export]
    macro_rules! vec_element_to_string {
        ($vec:expr) => {{
            let mut v2: Vec<String> = Vec::new();
            if $vec.len() > 0 {
                let vec1 = $vec.clone();
                v2 = vec1
                    .iter()
                    .map(|x| format!("{}", &x))
                    .collect::<Vec<String>>();
            }
            v2
        }};
    }
    ///## return the array elements arranged from outermost elements to the middle element, traveling clockwise (n x n)
    /// ```rust
    /// use doe::*;
    ///let v1 = snail_sort!(vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]);
    ///let v2 =  snail_sort!(vec![vec![1.1, 2.1, 3.1],vec![4.1, 5.1, 6.1],vec![7.1, 8.1, 9.1]]);
    ///assert_eq!(vec![1, 2, 3, 6, 9, 8, 7, 4, 5], v1);
    ///assert_eq!(vec![1.1, 2.1, 3.1, 6.1, 9.1, 8.1, 7.1, 4.1, 5.1], v2);
    /// ```
    #[macro_export]
    macro_rules! snail_sort {
        ($vec:expr) => {{
            fn snail<T: Copy>(matrix: &[Vec<T>]) -> Vec<T> {
                let mut ret = Vec::new();
                if matrix.len() == 0 {
                    return ret;
                }
                let mut width = matrix[0].len();
                let mut height = matrix.len();
                let mut cycle = 0;
                while width > 0 && height > 0 {
                    for x in cycle..width {
                        ret.push(matrix[cycle][x]);
                    }
                    for y in cycle + 1..height {
                        ret.push(matrix[y][width - 1]);
                    }
                    for x in (cycle..width - 1).rev() {
                        ret.push(matrix[height - 1][x]);
                    }
                    for y in (cycle + 1..height - 1).rev() {
                        ret.push(matrix[y][cycle]);
                    }
                    cycle += 1;
                    width -= 1;
                    height -= 1;
                }
                ret
            }
            let vec = $vec.clone();
            snail(&vec)
        }};
    }

    ///## mutiply two matrix
    /// ```rust
    /// use doe::*;
    ///let m1 = [[1, 2, -1], [-1, 3, 4], [1, 1, 1]].map(|s| s.to_vec()).to_vec();
    ///let m2 = [[5, 6], [-5, -6], [6, 0]].map(|s| s.to_vec()).to_vec();
    ///let mul_result1 = multiply_matrix!(&m1, &m2);
    ///assert_eq!(mul_result1, [[-11, -6], [4, -24], [6, 0]]);
    ///let m11 = [[1., 2., -1.], [-1., 3., 4.]].map(|s| s.to_vec()).to_vec();
    ///let m22 = [[5.5, 6.], [-5., -6.5]].map(|s| s.to_vec()).to_vec();
    ///let mul_result2 = multiply_matrix!(&m11, &m22);
    ///assert_eq!(mul_result2, [[-4.5, -7.0], [-20.5, -25.5]]);
    ///let m111 = [[1., 2., -1.], [-1., 3., 4.]].map(|s| s.to_vec()).to_vec();
    ///let m222 = [[5.5, 6.]].map(|s| s.to_vec()).to_vec();
    ///let mul_result3 = multiply_matrix!(&m111, &m222);
    ///assert_eq!(mul_result3, [[5.5, 6.0]]);
    /// ```
    #[macro_export]
    macro_rules! multiply_matrix {
        ($vec1:expr,$vec2:expr) => {{
            use core::ops;
            pub fn new<T: Clone + Copy>(val: T, m: usize, n: usize) -> Vec<Vec<T>> {
                //returb 0 created n*m matrix
                let mut mat: Vec<Vec<T>> = Vec::new();
                for _ in 0..m {
                    mat.push(vec![val; n].to_vec());
                }
                let vec = mat.clone();
                vec
            }
            pub fn multiply_matrix<
                T: Clone
                    + Copy
                    + std::fmt::Debug
                    + std::fmt::Display
                    + ops::Mul<Output = T>
                    + ops::Add<Output = T>
                    + ops::Div<Output = T>
                    + ops::Sub<Output = T>
                    + std::ops::AddAssign
                    + std::convert::From<i32>,
            >(
                matrix1: &Vec<Vec<T>>,
                matrix2: &Vec<Vec<T>>,
            ) -> Vec<Vec<T>> {
                let m = *&matrix2.len();
                pub fn generic_convert<T>(a: i32) -> T
                where
                    i32: std::convert::Into<T>,
                    T: std::convert::From<i32>,
                {
                    Into::into(a)
                }
                let val = generic_convert::<T>(0);
                let mut matrix3: Vec<Vec<T>> = new(val, *&matrix2.len(), *&matrix2[0].len());
                for i in 0..*&matrix2.len() {
                    for j in 0..*&matrix2[0].len() {
                        for k in 0..m {
                            matrix3[i][j] += matrix1[i][k] * matrix2[k][j];
                        }
                    }
                }
                matrix3
            }

            let vec1 = $vec1.clone();
            let vec2 = $vec2.clone();
            multiply_matrix(&vec1, &vec2)
        }};
    }
    ///## find the fist element and remove
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_element_remove!(vec!["15.", "2.9"], "2.9");
    ///let v2 = vec_element_remove!(vec![15, 2, 3, 2], 2);
    ///let v3 = vec_element_remove!(vec![0.15, 0.2, 0.2], 0.2);
    ///assert_eq!(vec!["15."], v1);
    ///assert_eq!(vec![15, 3, 2], v2);
    ///assert_eq!(vec![0.15, 0.2], v3);
    /// ```
    #[macro_export]
    macro_rules! vec_element_remove {
        ($vec:expr,$element:expr) => {{
            let mut vec = $vec.clone();
            match &vec.binary_search_by(|probe| probe.partial_cmp(&$element).unwrap()) {
                Ok(r) => {
                    vec.remove(*r);
                }
                Err(r) => {}
            }
            vec
        };};
    }
    ///## find the element and remove all
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_element_remove_all!(vec!["15.", "2.9", "0.9", "2.9", "2.9"], "2.9");
    ///assert_eq!(vec!["15.", "0.9"], v1);
    ///let v2 = vec_element_remove_all!(vec![15, 2, 3, 2], 2);
    ///assert_eq!(vec![15, 3], v2);
    ///let v3 = vec_element_remove_all!(vec![0.15, 0.2, 1.0, 0.2], 0.3);
    ///assert_eq!(vec![0.15, 0.2, 1.0, 0.2], v3);
    ///let v4 = vec_element_remove_all!(vec!["0".to_string(),"1".to_string(),"0".to_string()], "0".to_string());
    ///assert_eq!(vec!["1".to_string()], v4);
    /// ```
    #[macro_export]
    macro_rules! vec_element_remove_all {
        ($vec:expr,$element:expr) => {{
            let mut vec = $vec.clone();
            fn remove<T: Clone + PartialOrd<T>>(vec: Vec<T>, target: &T) -> Vec<T> {
                let mut v1 = vec.clone();
                for i in 1..v1.len() - 1 {
                    if v1[i - 1] == *target {
                        v1.remove(i - 1);
                    }
                }
                if v1[v1.len() - 1] == *target {
                    v1.remove(v1.len() - 1);
                }
                v1
            }
            remove(vec, &$element)
        };};
    }
    ///## find element position and collect into Vec<usize>
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_element_position_all!(vec![1, 2, 5, 3, 6, 2, 2], 2);
    ///assert_eq!(v1, vec![1, 5, 6]);
    ///let v2 = vec_element_position_all!(vec!["0".to_string(),"4".to_string(),"7".to_string(),"7".to_string(),], "7".to_string());
    ///assert_eq!(v2, vec![2,3]);
    /// ```
    #[macro_export]
    macro_rules! vec_element_position_all {
        ($vec:expr,$element:expr) => {{
            let mut vec = $vec.clone();
            fn position<T: Clone + PartialOrd<T>>(vec: Vec<T>, target: &T) -> Vec<usize> {
                let mut v1 = vec.clone();
                let mut re = vec![];
                for i in 0..v1.len() {
                    if v1[i] == *target {
                        re.push(i);
                    }
                }
                re
            }
            position(vec, &$element)
        };};
    }

    ///## slice vec by range
    /// ```rust
    ///use doe::*;
    ///let v1 = vec_slice!(vec![1.2, 1.5, 9.0], 0..2);
    ///let v2 = vec_slice!(vec![1, 1, 9, 90, 87, 0, 2], 4..6);
    ///let v3 = vec_slice!(vec![1.2, 1.5, 9.0], 0..3);
    ///let v4 = vec_slice!(vec![1.2, 1.5, 9.0], 1..3);
    ///let v5 = vec_slice!(vec!["1", "2", "3", "4", "5"], 2..5);
    ///let v6 = vec_slice!(vec!["1".to_string(),"2".to_string(),"3".to_string()], 1..2);
    ///assert_eq!(v1, vec![1.2, 1.5]);
    ///assert_eq!(v2, vec![87, 0]);
    ///assert_eq!(v3, vec![1.2, 1.5, 9.0]);
    ///assert_eq!(v4, vec![1.5, 9.0]);
    ///assert_eq!(v5, vec!["3", "4", "5"]);
    ///assert_eq!(v6,vec!["2".to_string()]);
    /// ```
    #[macro_export]
    macro_rules! vec_slice {
        ($vec:expr,$range:expr) => {{
            fn vec_slice<T: Clone>(vec: Vec<T>, range: std::ops::Range<usize>) -> Vec<T> {
                vec.get(range).unwrap().to_vec()
            }
            vec_slice($vec, $range)
        }};
    }

    ///## clone element by index
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_element_clone!(vec!["15.", "2.9"], 1);
    ///let v2 = vec_element_clone!(vec![15, 2, 3, 2], 2);
    ///let v3 = vec_element_clone!(vec![0.15, 0.2, 0.2], 0);
    ///let v4 = vec_element_clone!(vec![format!("1"),format!("2"),format!("3"),format!("4"),format!("5")],4);
    ///assert_eq!("2.9", v1);
    ///assert_eq!(3, v2);
    ///assert_eq!(0.15, v3);
    ///assert_eq!(format!("5"), v4);
    /// ```
    #[macro_export]
    macro_rules! vec_element_clone {
        ($vec:expr,$index:expr) => {{
            let vec = $vec.clone();
            let s = vec.get($index).unwrap();
            s.to_owned()
        };};
    }
    ///## remove file or folder
    /// ```ignore
    ///remove_file_or_folder!("./demo.txt");
    ///remove_file_or_folder!("./target");
    /// ```
    #[macro_export]
    macro_rules! remove_file_or_folder {
        ($path:expr) => {{
            use std::fs;
            use std::path::Path;
            pub fn rm(path: &Path) {
                if path.is_dir() {
                    fs::remove_dir_all(path).unwrap();
                } else if path.is_file() {
                    fs::remove_file(path).unwrap();
                }
            }
            let path = Path::new($path);
            rm(path);
        };};
    }
    ///## get vec type ,return string type value
    /// ```rust
    /// use doe::*;
    ///assert_eq!(vec_type!(vec![0.2_f64]), format!("Vec<f64>"));
    ///assert_eq!(vec_type!(vec![0.2_f32]), format!("Vec<f32>"));
    ///assert_eq!(vec_type!(vec![2_i32]), format!("Vec<i32>"));
    ///assert_eq!(vec_type!(vec![2_i128]), format!("Vec<i128>"));
    ///assert_eq!(vec_type!(vec![2_isize]), format!("Vec<isize>"));
    ///assert_eq!(vec_type!(vec![2_usize]), format!("Vec<usize>"));
    /// ```
    #[macro_export]
    macro_rules! vec_type {
        ($vec:expr) => {{
            use std::any::Any;
            pub fn vec_type(s: &dyn Any) -> String {
                let mut re = String::new();
                if s.is::<Vec<String>>() {
                    re = format!("Vec<String>");
                } else if s.is::<Vec<&str>>() {
                    re = format!("Vec<&str>");
                } else if s.is::<Vec<i128>>() {
                    re = format!("Vec<i128>");
                } else if s.is::<Vec<i64>>() {
                    re = format!("Vec<i64>");
                } else if s.is::<Vec<i32>>() {
                    re = format!("Vec<i32>");
                } else if s.is::<Vec<i16>>() {
                    re = format!("Vec<i16>");
                } else if s.is::<Vec<i8>>() {
                    re = format!("Vec<i8>");
                } else if s.is::<Vec<u128>>() {
                    re = format!("Vec<u128>");
                } else if s.is::<Vec<u64>>() {
                    re = format!("Vec<u64>");
                } else if s.is::<Vec<u32>>() {
                    re = format!("Vec<u32>");
                } else if s.is::<Vec<u16>>() {
                    re = format!("Vec<u16>");
                } else if s.is::<Vec<u8>>() {
                    re = format!("Vec<u8>");
                } else if s.is::<Vec<f64>>() {
                    re = format!("Vec<f64>");
                } else if s.is::<Vec<f32>>() {
                    re = format!("Vec<f32>");
                } else if s.is::<Vec<usize>>() {
                    re = format!("Vec<usize>");
                } else if s.is::<Vec<isize>>() {
                    re = format!("Vec<isize>");
                } else {
                    re = format!("");
                }
                re
            }
            vec_type(&$vec)
        };};
    }

    /// ## convert vec elements type
    /// ```rust
    /// use doe::*;
    ///let v1: Vec<f64> = vec_element_convert!(vec![1, 2], f64);
    ///let v2: Vec<i32> = vec_element_convert!(vec![1.0, 2.0], i32);
    ///let v3: Vec<i128> = vec_element_convert!(vec![1.0, 2.0], i128);
    ///let v4: Vec<i32> = vec_element_convert!(vec![1_usize, 2_usize], i32);
    ///let v5: Vec<i64> = vec_element_convert!(vec![0.15, 2.0], i64);
    ///assert_eq!(v1, vec![1.0, 2.0]);
    ///assert_eq!(v2, vec![1, 2]);
    ///assert_eq!(v3, vec![1, 2]);
    ///assert_eq!(v4, vec![1, 2]);
    ///assert_eq!(v5, vec![0, 2]);
    /// ```
    #[macro_export]
    macro_rules! vec_element_convert {
        ($vec:expr,$type:ty) => {{
            let vec = $vec.clone();
            let mut re: Vec<$type> = Vec::new();
            let re_type = vec_type!(re);
            if vec_type!(re) != format!("Vec<String>") {
                for item in &vec {
                    re.push(*item as $type);
                }
            }
            re
        };};
    }

    ///## expr return max value
    /// ```rust
    /// use doe::*;
    ///let re_max = max!(1, 20);
    ///assert_eq!(re_max,20);
    /// ```
    #[macro_export]
    macro_rules! max {
        ($x:expr) => ($x);
        ($x:expr, $($y:expr),+) => {
            std::cmp::max($x, max!($($y),+))
        }
    }
    ///## expr return min value
    /// ```rust
    /// use doe::*;
    ///let re_min = min!(10, 2, 2, 5, 4, 6);
    ///assert_eq!(re_min,2);
    /// ```
    #[macro_export]
    macro_rules! min {
        ($x:expr) => ($x);
        ($x:expr, $($y:expr),+) => {
            std::cmp::min($x, min!($($y),+))
        }
    }
    ///## convert binary string to decimal
    /// ```rust
    /// use doe::*;
    ///let d1 = binary_to_decimal!("01101",i128);
    ///assert_eq!(d1,13_i128);
    ///let d2 = binary_to_decimal!("00000000000010100110001",i64);
    ///assert_eq!(d2,1329_i64);
    ///let d3 = binary_to_decimal!("000011",i32);
    ///assert_eq!(d3,3_i32);
    ///let d4 = binary_to_decimal!("000101",i16);
    ///assert_eq!(d4,5_i16);
    ///let d5 = binary_to_decimal!("001001",i8);
    ///assert_eq!(d5,9_i8);
    /// ```
    #[macro_export]
    macro_rules! binary_to_decimal {
        ($binary_string:expr,$decimal_type:ty) => {{
            fn binary_to_decimal(num: impl ToString) -> $decimal_type {
                let mut sum = 0 as $decimal_type;
                let vec = num
                    .to_string()
                    .chars()
                    .map(|x| <$decimal_type>::from(x.to_digit(10).unwrap() as $decimal_type))
                    .collect::<Vec<$decimal_type>>();
                for (index, item) in vec.iter().rev().enumerate() {
                    sum += <$decimal_type>::pow(2, index as u32) * item;
                }
                sum
            }
            binary_to_decimal($binary_string)
        }};
    }
    ///## expr return memory address
    /// ```rust
    /// use doe::*;
    ///let d1 = binary_to_decimal!("01101",i128);
    ///println!("{:?}",memory_address!(d1));//0x7ffcac734f08
    /// ```
    #[macro_export]
    macro_rules! memory_address {
        ($x:expr) => {{
            &$x as *const _
        }};
    }

    ///## Merge two Vec return merged Vec
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_merge!(vec![0, 1, 2], vec![5, 6, 7]);
    ///assert_eq!(vec![0, 1, 2, 5, 6, 7],v1);
    ///let v2 = vec_merge!(vec![0., 1., 2.], vec![5., 6., 7.]);
    ///assert_eq!(vec![0., 1., 2., 5., 6., 7.],v2);
    ///```
    #[macro_export]
    macro_rules! vec_merge {
        ($vec1:expr,$vec2:expr) => {{
            let mut re = vec![];
            for item in $vec1.iter() {
                re.push(item.to_owned());
            }
            for item in $vec2.iter() {
                re.push(item.to_owned());
            }
            re
        }};
    }

    ///## take size of elements and return a new vec
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_element_take!(vec![0, 1, 2],2);
    ///assert_eq!(vec![0,1],v1);
    ///```
    #[macro_export]
    macro_rules! vec_element_take {
        ($vec:expr,$size:expr) => {{
            let mut re = vec![];
            for i in 0..$size {
                re.push(vec_element_clone!($vec, i));
            }
            re
        }};
    }

    ///## zip two vec elements in tuple
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_zip!(vec![0, 1, 2],vec![0, 1, 2]);
    ///assert_eq!(vec![(0,0),(1,1),(2,2)],v1);
    ///```
    #[macro_export]
    macro_rules! vec_zip {
        ($vec1:expr,$vec2:expr) => {{
            let mut re = vec![];
            if $vec1.len() == $vec2.len() {
                for i in 0..$vec1.len() {
                    re.push((vec_element_clone!($vec1, i), vec_element_clone!($vec2, i)));
                }
            }
            re
        }};
    }

    ///## enumerate all indexs and elements collect tuple of vec
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_enumerate!(vec![12, 11, 20]);
    ///assert_eq!(vec![(0,12),(1,11),(2,20)],v1);
    ///```
    #[macro_export]
    macro_rules! vec_enumerate {
        ($vec:expr) => {{
            let mut re = vec![];
            for (index, element) in $vec.iter().enumerate() {
                re.push((index, vec_element_clone!($vec, index)));
            }
            re
        }};
    }
    ///## sort vec and return sorted vec
    /// ```rust
    /// use doe::*;
    ///let v1 = vec_sort!(vec![10, 2, 3]);
    ///assert_eq!(vec![2,3,10],v1);
    ///let v2 = vec_sort!(vec![1.8, 2.5, 0.3]);
    ///assert_eq!(vec![0.3,1.8,2.5],v2);
    ///```
    #[macro_export]
    macro_rules! vec_sort {
        ($vec:expr) => {{
            let mut re = $vec.clone();
            re.sort_by(|a, b| a.partial_cmp(b).unwrap());
            re
        }};
    }
    ///## has stable rust nightly return bool
    /// ```ignore
    /// use doe::*;
    /// let v1 = has_nightly_compiler!();
    /// assert_eq!(v1, true);
    ///```
    #[cfg(not(target_arch = "wasm32"))]
    #[macro_export]
    macro_rules! has_nightly_compiler {
        () => {{
            fn has_nightly_compiler() -> bool {
                use std::process;
                match process::Command::new("cargo")
                    .arg("+nightly")
                    .arg("help")
                    .stdout(process::Stdio::null())
                    .stderr(process::Stdio::null())
                    .status()
                {
                    Ok(exit_status) => exit_status.success(),
                    Err(_) => false,
                }
            }
            has_nightly_compiler()
        }};
    }

    ///## has stable rust compiler return bool
    /// ```rust
    /// use doe::*;
    /// let v1 = has_stable_compiler!();
    /// assert_eq!(v1, false);
    ///```
    #[cfg(not(target_arch = "wasm32"))]
    #[macro_export]
    macro_rules! has_stable_compiler {
        () => {{
            fn has_stable_compiler() -> bool {
                use std::process;
                match process::Command::new("cargo")
                    .arg("+stable")
                    .arg("help")
                    .stdout(process::Stdio::null())
                    .stderr(process::Stdio::null())
                    .status()
                {
                    Ok(exit_status) => exit_status.success(),
                    Err(_) => false,
                }
            }
            has_stable_compiler()
        }};
    }

    ///## run a function once after a particularized delay(millis)
    /// ```ignore
    /// use doe::*;
    ///set_timeout!(||{
    ///    println!("ok");
    ///},3000);
    ///```
    #[cfg(not(target_arch = "wasm32"))]
    #[macro_export]
    macro_rules! set_timeout {
        ($fn:expr,$time:expr) => {{
            fn set_timeout<F>(mut func: F, time: u64)
            where
                F: Copy + Fn(),
            {
                use std::time::Duration;
                std::thread::sleep(Duration::from_millis(time));
                func();
            }
            set_timeout($fn, $time);
        }};
    }

    ///## run a function repeatedly, beginning after some millis, then repeating continuously at the given interval.
    /// ```ignore
    /// use doe::*;
    ///set_interval!(||{
    ///    println!("ok");
    ///},3000);
    ///```
    #[cfg(not(target_arch = "wasm32"))]
    #[macro_export]
    macro_rules! set_interval {
        ($fn:expr,$time:expr) => {{
            loop {
                set_timeout!($fn, $time);
            }
        }};
    }

    ///## get current UTC-timestamp
    /// ```rust
    /// use doe::*;
    /// let t = utc_timestamp!();
    /// eprintln!("{}", t);
    /// ```
    #[cfg(not(target_arch = "wasm32"))]
    #[macro_export]
    macro_rules! utc_timestamp {
        () => {{
            std::time::SystemTime::now()
                .duration_since(std::time::SystemTime::UNIX_EPOCH)
                .unwrap_or_default()
                .as_secs_f64()
        }};
    }

    ///## macro for HashMap
    ///```rust
    /// use doe::*;
    /// use std::collections::HashMap;
    /// let mut map:HashMap<i32,i32> = hashmap!();
    /// map.insert(0, 1);
    /// let map1 = hashmap!(2=>5,3=>4);
    ///```
    #[macro_export]
    macro_rules! hashmap {
        () => {{
            std::collections::HashMap::new()
        }};
        ($(||)+) => {{
            std::collections::HashMap::new
        }};
        ($($k: expr => $v: expr),+ $(,)*) => {{
            let mut m = std::collections::HashMap::with_capacity([$(&$k),*].len());
            $(m.insert($k, $v);)*
            m
        }};

    }
    ///## macro for BTreeMap
    ///```rust
    /// use doe::*;
    /// use std::collections::BTreeMap;
    /// let mut map:BTreeMap<i32,i32> = btreemap!();
    /// map.insert(0, 1);
    /// let map1 = btreemap!(2=>5,3=>4);
    ///```
    #[macro_export]
    macro_rules! btreemap {
        () => {{
            std::collections::BTreeMap::new()
        }};
        ($(||)+) => {{
            std::collections::BTreeMap::new
        }};
        ($($k: expr => $v: expr),+ $(,)*) => {{
            let mut m = std::collections::BTreeMap::new();
            $(m.insert($k, $v);)*
            m
        }};

    }
    ///  ## implment targets! for return Vec<(Box\<dyn ToString>,Box\<dyn ToString>)>
    /// ```rust
    ///fn main() {
    ///    use doe::Print;
    ///    use doe::Str;
    ///    "this is a {s},I like Trait Object {p}%"
    ///    .format(vec![(Box::new("{s}"),Box::new("demo")),(Box::new("{p}"),Box::new(100))]).println();//this is a demo,I like Trait Object 100%
    ///     use doe::targets;
    ///     "this is a {d},I like Trait Object {p}}%"
    ///     .format(targets!{"{d}"=>"demo","{p}"=>100})
    ///     .println(); //this is a demo,I like Trait Object 100%
    ///}
    /// ```
    #[macro_export]
    macro_rules! targets {
        ($($key:expr => $value:expr),*) => {
            vec![
                $((Box::new($key), Box::new($value))),*
            ]
        };
    }
    /// implmemt Display for Struct
    /// ```rust
    ///fn main() {
    ///    use std::sync::{Arc, Mutex};
    ///    use doe::*;
    ///    struct Doe{
    ///        pub name:String,
    ///        pub nickname: Box<str>,
    ///        key:Arc<Mutex<usize>>
    ///    }
    ///    impl_display!(Doe,name,nickname,key);
    ///    impl_debug!(Doe,name,nickname,key);
    ///    let d = Doe{name:"andrew".to_string(), nickname: Box::from("func"),key:Arc::new(Mutex::new(15))};
    ///    println!("{:?}",d);
    ///    println!("{}",d);
    ///}
    /// ```
    ///
    #[macro_export]
    macro_rules! impl_display {
        ($struct_name:ident, $($key:ident),*) => {
            impl std::fmt::Display for $struct_name {
                fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
                    write!(f, "{} {{", stringify!($struct_name))?;
                    $(
                        write!(f, " {}: {:?},", stringify!($key), self.$key)?;
                    )*
                    write!(f, "}}")
                }
            }
        };
    }
    /// implmemt Debug for Struct
    /// ```rust
    ///fn main() {
    ///    use std::sync::{Arc, Mutex};
    ///    use doe::*;
    ///    struct Doe{
    ///        pub name:String,
    ///        pub nickname: Box<str>,
    ///        key:Arc<Mutex<usize>>
    ///    }
    ///    impl_display!(Doe,name,nickname,key);
    ///    impl_debug!(Doe,name,nickname,key);
    ///    let d = Doe{name:"andrew".to_string(), nickname: Box::from("func"),key:Arc::new(Mutex::new(15))};
    ///    println!("{:?}",d);
    ///    println!("{}",d);
    ///}
    /// ```
    ///
    #[macro_export]
    macro_rules! impl_debug {
        ($struct_name:ident, $($key:ident),*) => {
            impl std::fmt::Debug for $struct_name {
                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                    f.debug_struct(stringify!($struct_name))
                        $(.field(stringify!($key), &self.$key))*
                        .finish()
                }
            }
        };
    }
    /// implmemt Clone for Struct
    /// ```rust
    ///fn main() {
    ///    use std::sync::{Arc, Mutex};
    ///    use doe::*;
    ///    struct Doe{
    ///        pub name:String,
    ///        pub nickname: Box<str>,
    ///        key:Arc<Mutex<usize>>
    ///    }
    ///    impl_clone!(Doe,name,nickname,key);
    ///    impl_debug!(Doe,name,nickname,key);
    ///    let d = Doe{name:"andrew".to_string(), nickname: Box::from("func"),key:Arc::new(Mutex::new(15))};
    ///    println!("{:?}",d.clone());
    ///}
    /// ```
    ///
    #[macro_export]
    macro_rules! impl_clone {
        ($struct_name:ident, $($key:ident),*) => {
            impl Clone for $struct_name {
                fn clone(&self) -> Self {
                    // clone each element
                    $(
                        let $key = self.$key.clone();
                    )*

                    // create a new instance
                    $struct_name {
                        $(
                            $key,
                        )*
                    }
                }
            }
        }
    }
    /// implmemt Default for Struct
    /// ```rust
    ///fn main() {
    ///    use std::sync::{Arc, Mutex};
    ///    use doe::*;
    ///    struct Doe{
    ///        pub name:String,
    ///        pub nickname: Box<str>,
    ///        key:Arc<Mutex<usize>>
    ///    }
    ///    impl_default!(Doe,name,nickname,key);
    ///    impl_debug!(Doe,name,nickname,key);
    ///    let d = Doe::default();
    ///    println!("{:?}",d);
    ///}
    /// ```
    ///
    #[macro_export]
    macro_rules! impl_default {
        ($struct_name:ident, $($key:ident),*) => {
            impl Default for $struct_name {
                fn default() -> Self {
                    $struct_name {
                        $(
                            $key: Default::default(),
                        )*
                    }
                }
            }
        }
    }
    /// implmemt Drop for Struct
    /// ```rust
    ///fn main() {
    ///    use std::sync::{Arc, Mutex};
    ///    use doe::*;
    ///    struct Doe{
    ///        pub name:String,
    ///        pub nickname: Box<str>,
    ///        key:Arc<Mutex<usize>>
    ///    }
    ///    impl_default!(Doe,name,nickname,key);
    ///    impl_debug!(Doe,name,nickname,key);
    ///    impl_drop!(Doe,name,nickname,key);
    ///    let d = Doe::default();
    ///    println!("{:?}",d);
    ///}
    /// ```
    ///
    #[macro_export]
    macro_rules! impl_drop {
        ($struct_name:ident, $($key:ident),*) => {
            impl Drop for $struct_name {
                fn drop(&mut self) {
                    $(
                        let _ = &self.$key;
                    )*
                }
            }
        }
    }
    /// implement Default,Debug,Display,Clone,Drop for struct
    /// ```rust
    ///fn main() {
    ///    use std::sync::{Arc, Mutex};
    ///    use doe::*;
    ///    struct Doe{
    ///        pub name:String,
    ///        pub nickname: Box<str>,
    ///        key:Arc<Mutex<usize>>
    ///    }
    ///    impl_all!(Doe,name,nickname,key);
    ///    let d = Doe{name:"andrew".to_string(), nickname: Box::from("func"),key:Arc::new(Mutex::new(15))};
    ///    let d1 = Doe::default();
    ///    let d2 = d1.clone();
    ///    println!("{:?}",d);
    ///    println!("{}",d1);
    ///}
    /// ```
    #[macro_export]
    macro_rules! impl_all {
        ($struct_name:ident, $($key:ident),*) => {
            $crate::impl_debug!($struct_name, $($key),*);
            $crate::impl_display!($struct_name, $($key),*);
            $crate::impl_clone!($struct_name, $($key),*);
            $crate::impl_drop!($struct_name, $($key),*);
            $crate::impl_default!($struct_name, $($key),*);
        }
    }

    ///## implments Bfn struct and bfn! macro for Box<dyn Fn()> trait object
    ///```rust
    ///fn main() {
    ///    use doe::DebugPrint;
    ///    use doe::bfn;
    ///    use doe::Bfn;
    ///    #[derive(Debug)]
    ///    struct Demo<'a>{
    ///        name:&'a str
    ///    }
    ///    let f0 = bfn!(||{println!("ok");});
    ///    f0.call();
    ///    fn func()->Demo<'static>{
    ///        let d = Demo{name: "andrew"};
    ///        d
    ///    }
    ///    let f1 = bfn!(func);
    ///    f1.call().dprintln();
    ///
    ///    fn sum()->usize{
    ///        9+89
    ///    }
    ///    let f2 = Bfn::new(Box::new(sum));//or bfn!(sum);
    ///    f2.call().dprintln();
    ///}
    ///```
    #[macro_export]
    macro_rules! bfn {
        ($v:expr) => {
            $crate::structs::structs::Bfn::new(Box::new($v))
        };
    }

    ///## implments Bts struct and bts! macro for Box<\dyn ToString> trait object
    /// ```rust
    ///fn main() {
    ///    use doe::DebugPrint;
    ///    use doe::Bts;
    ///    use doe::bts;
    ///    let mut s:Bts =  bts!("Trait Object, it's ");
    ///    s.push(bts!(100));
    ///    s.push_str("% safe");
    ///    s.dprintln();//"Trait Object, it's 100% safe"
    ///    s.as_bytes().dprintln();//[84, 114, 97, 105, 116, 32, 79, 98, 106, 101, 99, 116, 44, 32, 105, 116, 39, 115, 32, 49, 48, 48, 37, 32, 115, 97, 102, 101]
    ///    s.chars().dprintln();//['T', 'r', 'a', 'i', 't', ' ', 'O', 'b', 'j', 'e', 'c', 't', ',', ' ', 'i', 't', '\'', 's', ' ', '1', '0', '0', '%', ' ', 's', 'a', 'f', 'e']
    ///    let b = Into::<Bts>::into("b".to_string());
    ///    let b = Bts::from("demo");
    ///}
    ///```
    #[macro_export]
    macro_rules! bts {
        ($v:expr) => {{
            $crate::structs::structs::Bts::new(Box::new($v))
        }};
    }
    #[macro_export]
    macro_rules! has_powershell {
        () => {{
            fn has_powershell() -> bool {
                use std::process::Command;
                let output = Command::new("powershell")
                    .args(&["-Command", "$PSVersionTable.PSVersion.Major"])
                    .output()
                    .expect("Failed to execute PowerShell command");

                if output.status.success() {
                    let _ = String::from_utf8_lossy(&output.stdout);
                    return true;
                } else {
                    return false;
                }
            }
            has_powershell()
        }};
    }
}
