# Doe - A Versatile Rust Utility Crate

[![Crates.io](https://img.shields.io/crates/v/doe)](https://crates.io/crates/doe)
[![Documentation](https://docs.rs/doe/badge.svg)](https://docs.rs/doe)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Doe is a versatile Rust crate that significantly enhances the development workflow by offering an extensive collection of useful macros and utility functions. It streamlines common tasks and provides convenient features for clipboard management, state management, keyboard input, and mouse interaction. Additionally, doe includes robust cryptographic functions, enabling developers to easily integrate secure encryption, decryption, and hashing capabilities into their applications, ensuring data integrity and confidentiality.

## Features

### Core Features
- **Clipboard Management**: Simplifies clipboard operations
- **Cryptographic Functions**: AES, RSA, SHA, MD5 and Blake3 implementations
- **File System Utilities**: Advanced file operations and management
- **Random Number Generation**: LCG-based random number generator
- **System Utilities**: Process management and system commands

### Optional Features
To use specific features, add them to your Cargo.toml:

```toml
[dependencies]
doe = { version = "1.0", features = ["ctf", "clip", "mouse"] }
```

### Available Features:

| Feature      | Description                                      | Command                              |
|--------------|--------------------------------------------------|--------------------------------------|
| **ctf**      | String manipulation and encoding utilities       | `cargo add doe -F ctf`               |
| **clip**     | Clipboard management                             | `cargo add doe -F clip`              |
| **mouse**    | Mouse input simulation                           | `cargo add doe -F mouse`             |
| **keyboard** | Keyboard input simulation                        | `cargo add doe -F keyboard`          |
| **kcm**      | Keyboard, clipboard, and mouse combined          | `cargo add doe -F kcm`               |
| **xlsx**     | Excel file manipulation                          | `cargo add doe -F xlsx`              |
| **docx**     | Word document manipulation                       | `cargo add doe -F docx`              |
| **date**     | Date and time utilities                          | `cargo add doe -F date`              |
| **screenshot** | Screenshot capture and processing              | `cargo add doe -F screenshot`        |
| **images**   | Image manipulation                               | `cargo add doe -F images`            |
| **crypto**   | Cryptographic functions                          | `cargo add doe -F crypto`            |
| **asyncrs**  | Async runtime utilities                          | `cargo add doe -F asyncrs`           |
| **logger**   | Logging utilities                                | `cargo add doe -F logger`            |
| **sqlserver** | SQL Server database operations                  | `cargo add doe -F sqlserver`         |
| **axumserver** | Axum server utilities                          | `cargo add doe -F axumserver`        |
| **ip_addr**  | IP address utilities                             | `cargo add doe -F ip_addr`           |
| **http**     | HTTP client and server utilities                 | `cargo add doe -F http`              |
| **process**  | Process management utilities                     | `cargo add doe -F process`           |
| **json**     | JSON manipulation utilities                      | `cargo add doe -F json`              |

## Modules
### Core Modules
- **asyncrs**: Async runtime utilities for concurrent programming
- **clipboard**: Clipboard operations for copying and pasting data
- **color**: Color format conversions between RGB and HEX
- **consts**: Common constants used throughout the crate
- **crypto**: Cryptographic functions including AES, RSA, SHA, MD5 and Blake3
- **ctf**: String manipulation and encoding utilities
- **date**: Date and time utilities
- **docx**: Word document manipulation
- **fs**: File system operations
- **httprs**: HTTP request utilities
- **images**: Image manipulation
- **ip_addr**: IP address parsing and manipulation
- **json**: JSON manipulation
- **keyboard**: Keyboard input simulation
- **logger**: Logging utilities
- **macros**: Utility macros
- **mouse**: Mouse input simulation
- **process**: Process management
- **rand**: Random number generation
- **screenshot**: Screenshot utilities
- **axumserver**: Axum server utilities
- **sqlserver**: SQL Server database operations
- **structs**: Custom data structures
- **timer**: Timer utilities
- **traits**: Shared behavior definitions
- **xlsx**: Excel file manipulation
- **zoml**: ZOML format utilities

## Usage

Add doe to your Cargo.toml:

```toml
[dependencies]
doe = "1.0"
```

# Examples
### crypto example
```rust
let data = "this is data".as_bytes();
let enc_data = doe::crypto::aes::aes_ecb_encrypt("12345678123456781234567812345678".as_bytes(),"1234567812345678".as_bytes(),data).unwrap();
let dec_data = doe::crypto::aes::aes_ecb_decrypt("12345678123456781234567812345678".as_bytes(),"1234567812345678".as_bytes(),&enc_data).unwrap();
println!("data:{:?}",&data);
println!("enc_data:{:?}",&enc_data);
println!("dec_data:{:?}",&dec_data);
println!("blake3:{:?}",doe::crypto::blake3_xof("dnrops".as_bytes(), 10));
```
### keyboard example
```rust
// cargo add doe -F kcm
use doe::keyboard::key_click;
use doe::keyboard::key_press;
use doe::keyboard::key_release;
use doe::keyboard::KeyCode;
use doe::mouse::mouse_drag;
use doe::mouse::move_to_paste;
use doe::mouse::move_to_press_left;
use doe::*;
use keyboard::exit_if_click_esc;
let list = vec!["iphone","ipad","macbook"];

// crete new baogao
move_to_press_left(857, 588).sleep(1.0); //#000000

// create fengmian
move_to_paste(1540, 853, "Apple").sleep(1.0); //#000000
move_to_paste(1360, 882, "ID").sleep(1.0); //#000000

// add shuoming
move_to_paste(772, 464, "Discription").sleep(1.0); //#ffffff
mouse_drag((894, 719).into(), (821, 716).into()).sleep(1.0); //#f0f0f0
key_click("2024-01-23").sleep(1.0);
move_to_press_left(740, 305).sleep(1.0); //#f0f0f0

for name in list {
    // add baobao
    move_to_press_left(476, 253).sleep(1.0); //#ffffff

    // name
    move_to_press_left(796, 331).sleep(1.0); //#ffffff
    key_click("end");
    key_click("shift+home");
    set_clipboard(name).unwrap().sleep(0.5);
    key_click("ctrl+v");

    // add fujian
    move_to_press_left(870, 587).sleep(1.0); //#000000
    mouse_drag((893, 818).into(), (814, 816).into()).sleep(1.0); //#f0f0f0
    key_click("2024-01-23").sleep(1.0);
    move_to_press_left(723, 206).sleep(1.0); //#000000
}

// set taoshu
move_to_paste(1341, 910, "New_name").sleep(1.0); //#000000
```
### docx_replace
```rust
//finds all 'name' and replace with 'andrew'
use doe::*;
docx::docx_replace("./name.docx","name","andrew").unwrap();
docx::docx_get_content("./name.docx").unwrap().dprintln();
docx::docx_remove_read_only("./name.docx").unwrap();
```
### Spawn trait
```rust
use doe::*;
use doe::keyboard::exit_if_click_esc;
let t1 = run.spawn();
let t2 = exit_if_click_esc.spawn();
t1.join();
t2.join();
```
### listen keybord and mouse
```rust
fn main() {
    use doe::keyboard::listen_keybord;
    use doe::mouse::listen_mouse_position;
    use doe::mouse::listen_mouse_scroll;
    use doe::mouse::listen_mouse_click;
    let t1 = std::thread::spawn(||{
        listen_keybord();
    });
    let t2 = std::thread::spawn(||{
        listen_mouse_position();
    });
    let t3 = std::thread::spawn(||{
        listen_mouse_scroll();
    });
    let t4 = std::thread::spawn(||{
        listen_mouse_click();
    });
    t1.join().unwrap();
    t2.join().unwrap();
    t3.join().unwrap();
    t4.join().unwrap();
}
```
### automater

generate script
 ```rust
 fn main(){
     use doe::mouse::listen_all;
     listen_all();
 }
 ```
run to generate script

`cargo r > script.m`

script.m
```sh
 move_to(1562,6);
 press("left");
 move_to(1453,20);
 press("left");
 move_to(342,515);
 scoll_down();
 move_to(496,560);
 press("left");
 move_to(304,454);
 key_press(8);
 key_release(8);
 press("left");
 key_press(162);
 key_press(67);
```
 run script
 ```rust
  use doe::mouse::automater;
  let script =  include_str!("../script.m");
  automater(script);
 ```
### mouse automater
```rust
fn main() {
    use doe::mouse;
    let script = r#"
        move_to::217::135
        sleep::1
        move_to_press_left::189::137
        sleep::1
        move_to_press_left::198::185
        sleep::1
        move_drag::655::343::678::330
        sleep::1
        // script comment
        move_to_paste::479::715::page demo is ok
    "#
    .trim();
    mouse::mouse_automater(script);
}
```
### mouse press left drag
 ```rust
fn main(){
    use doe::mouse::mouse_drag;
    mouse_press_left_drag((543,446).into(), (590,460).into());
    mouse_drag((543,446).into(), (590,460).into(),"left");
}
 ```
```rust
fn main()->doe::DynError<()> {
    use doe::clipboard::get_clipboard;
    use doe::clipboard::set_clipboard;
    set_clipboard("rust").unwrap();
    let clip = get_clipboard().unwrap();
    assert_eq!("rust",clip);
    Ok(())
}
```
```
cargo add doe -F keyboard
```
 ## keyboard example
 ```rust
fn main(){
    use doe::keyboard::key_press;
    use doe::keyboard::key_release;
    use doe::keyboard::listen_mouse_position;
    use doe::keyboard::get_mouse_position;
    use doe::keyboard::listen_keybord;
 
    use doe::keyboard::KeyCode;
    key_press(KeyCode::COMMAND);
    key_press(KeyCode::V);
    key_release(KeyCode::V);
    // listen key press and release
    listen_keybord();
}
 ```
## control mouse
```
cargo add doe -F mouse
#arch linux
sudo pacman -S xdotool
#Fedora OR Red Hat
sudo dnf install libxdo-devel
#Ubuntu OR Debian 
sudo apt install libxdo-dev
#Cargo.toml add
[build]
rustflags = ["-L", "/usr/local/lib"]
#OR Cargo.toml add
[build]
rustflags = ["-l", "xdo"]
```
```rust
fn main()->doe::DynError<()> {
    use std::time::Duration;
    use doe::mouse::press;
    move_to(300, 700);
    press("left");
    move_to_with_duration(0, 0,Duration::from_secs(5));
    move_and_press_right(800,900);
    press("right");
    Ok(())
}
```
## CopyString is a structure that implements the Copy trait
```rust
 use doe::CopyString;
 let mut s = CopyString::default();
 s.push_str("11");
 s.push_str("22");
 s.push_str("33");
 s.push_str("44");
 dbg!(s);
 s.println();
 let a = s;
 let b = a;
 b.println();
```

## implments Bts struct and bts! 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().println();

    fn sum()->usize{
        9+89
    }
    let f2 = Bfn::new(Box::new(sum));//or bfn!(sum);
    f2.call().println();
}
```
## 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.println();//"Trait Object, it's 100% safe"
    s.as_bytes().println();//[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().println();//['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");
}
```
## implmemt Debug,Display,Clone,Default,Drop trait 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);
    impl_default!(Doe,name,nickname,key);
    impl_clone!(Doe,name,nickname,key);
    impl_drop!(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();
    println!("{:?}",d);
    println!("{}",d1);
}
```
## implment format for impl ToString
```rust
fn main() {
    use doe::Print;
    use doe::Str;
    use doe::targets;
    "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%
    "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%
}
```
## implment print println eprint eprintln for impl Display, impl Debug
```rust
use doe::Print;
use doe::DebugPrint;
"printable text".print();//impl Display
"printable text".println();
"printable text".eprintln();
#[derive(Debug)]
struct DebugPrintDemo{}//impl Debug
let d = DebugPrintDemo{};
d.dprint();
d.dprintln();
d.deprintln();
```

## implment targets! for return Vec<(Box\<dyn ToString>,Box\<dyn ToString>)>
```rust
fn main() {
    use doe::targets;
    use doe::Print;
    use doe::Str;
    "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%
}
```
## run timer by send stop_massge by channel
```rust
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let (sender, receiver) = mpsc::channel::<bool>();
    let t1 = thread::spawn(move || {
        thread::sleep(Duration::from_secs(5));
        sender.send(true).unwrap();
    });
    let t2 = thread::spawn(move || {
        run_timer_by_channel(Duration::from_secs(1), receiver, Box::new(|| {
            println!("running..");
        }));
    });
    t1.join().expect("Thread panicked");
    t2.join().expect("Thread panicked");
}
```
## run timer by shared state
 ```rust
fn main() {
    use std::sync::{Arc, Mutex};
    let run_state = Arc::new(Mutex::new(true));

    let t1 = std::thread::spawn({
        let run_state = Arc::clone(&run_state);
        move || {
            std::thread::sleep(std::time::Duration::from_secs(5));
            *run_state.lock().unwrap() = false;
        }
    });

    let t2 = std::thread::spawn({
        let run_state = Arc::clone(&run_state);
        move || {
            run_timer_by_state(
                std::time::Duration::from_secs(1),
                run_state,
                Box::new(|| {
                    // Function body goes here
                    println!("Running...");
                }),
            );
        }
    });

    // Wait for the threads to finish
    t1.join().expect("Thread panicked");
    t2.join().expect("Thread panicked");

}
 ```
## run timer anguments :start_time:Instant,step_time:Duration,stop_time:Duration,func:Box<dyn Fn()>
 ```rust
fn run(){
     println!("running ");
}
run_timer(std::time::Instant::now(),std::time::Duration::from_secs(1),std::time::Duration::from_secs(5),Box::new(run));
 ```
## useage of fs module
```rust
fn main() {
    use doe::fs::*;
    use doe::DebugPrint;
    use doe::Str;
    use std::ops::Deref;
    use doe::fs::home_dir;
    use doe::DebugPrint;
    home_dir().display().dprintln();

    // append data to file
    append_data_to_file("demo.txt", "demo".as_bytes().to_vec()).unwrap();

    // get all files and folders
    walk_dir(".".to_path().deref()).unwrap().println();

    // get all folders
    walk_dir_get_files(".".to_path().deref()).unwrap().println();

    // get all folders
    walk_dir_get_folders(".".to_path().deref())
        .unwrap()
        .println();

    //move file the directory to a new directory
    move_file(
        "/Users/ryanandrew/code/test/t1/demo.zip".to_path().deref(),
        "/Users/ryanandrew/code/test/t2/d2.zip".to_path().deref(),
    )
    .unwrap();

    //copy file the directory to a new directory
    copy_file(
        "/Users/ryanandrew/code/test/t1/demo.zip".to_path().deref(),
        "/Users/ryanandrew/code/test/t2/d2.zip".to_path().deref(),
    )
    .unwrap();
    //move all files in the directory to a new directory
    move_folder(
        "/Users/ryanandrew/code/test/t1".to_path().deref(),
        "/Users/ryanandrew/code/test/t2/t1".to_path().deref(),
    )
    .unwrap();

    //copy all files in the directory to a new directory
    copy_folder(
        "/Users/ryanandrew/code/test/d1".to_path().deref(),
        "/Users/ryanandrew/code/test/d2".to_path().deref(),
    )
    .unwrap();
}
```
## like pythons os.system() function
```rust
pub fn run() {
    //linux and macos
    system!("ping bing.com");
    // in windows
    system_powershell!("ls");
    system!("python -m http.server"); //run in cmd
}
```
## implment cut format for str and String
 ```rust
use doe::Str;
let a = "this is a demo {}";
let c = a.cut(-1,-2,1);
let f = a.format("so {}").format("how good is");
println!("{:?}",f);
println!("{:?}",c);
 ```
## convert type
 ```rust
  use doe::*;
  let s = as_to!(5., i64);
  assert_eq!(5, s);
 ```
##  if type is i8 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_i8(&5_i8),true);
 ```
##  if type is i16 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_i16(&5_i16),true);
 ```
##  if type is i32 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_i32(&5_i32),true);
 ```
##  if type is i64 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_i64(&5_i64),true);
 ```
##  if type is i128 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_i128(&5_i128),true);
 ```
##  if type is f32 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_f32(&5.0_f32),true);
 ```
##  if type is f64 return true
 ```rust
 use doe::*;
 assert_eq!(macros::is_f64(&5.0_f64),true);
 ```
## returns a raised to the b power
 ```rust
 use doe::*;
 let p = powf!(2.,2.);
 assert_eq!(p,4.0);
 ```
## get argument and collect into Vec\<String\>
 ```rust
 use doe::*;
 //cargo run -- -n 100
 let arg = args!();
 assert_eq!(arg,vec![format!("-n"),format!("100")]);
 ```
## get user input from terminal,return String
 ```rust
 use doe::*;
 let s = input!();
 println!("{:?}",s);
 ```
## 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")]);
 ```
## 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")]]);
 ```
## 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]);
 ```
## 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]);
 ```
## 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);
 ```
## 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);
 ```
## 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);
 ```
## 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]]);
 ```
## 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);
 ```
## 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]);
 ```
## slice vec by range
 ```rust
 use doe::*;
let v1 = vec_slice!(vec![1.2, 1.5, 9.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], [..]);
let v4 = vec_slice!(vec![1.2, 1.5, 9.0], [1..]);
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..]);
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(),"3".to_string()]);
 ```
## 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);
 ```
## remove file or folder
 ```rust
remove_file_or_folder!("./demo.txt");
remove_file_or_folder!("./target");
 ```
## 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>"));
 ```
 ## 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]);
 ```
## expr return max value
 ```rust
 use doe::*;
let re_max = max!(1, 20);
assert_eq!(re_max,20);
 ```
## expr return min value
 ```rust
 use doe::*;
let re_min = min!(10, 2, 2, 5, 4, 6);
assert_eq!(re_min,2);
 ```
## 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);
 ```
## expr return memory address
 ```rust
 use doe::*;
let d1 = binary_to_decimal!("01101",i128);
println!("{:?}",memory_address!(d1));//0x7ffcac734f08
 ```
## 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);
 ```
## 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);
 ```
## 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);
 ```
## 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);
 ```
## 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);
 ```
## has stable rust nightly return bool
 ```rust
 use doe::*;
 let v1 = has_nightly_compiler!();
 assert_eq!(v1, true);
 ```
## has stable rust compiler return bool
 ```rust
 use doe::*;
 let v1 = has_stable_compiler!();
 assert_eq!(v1, false);
 ```
## run command
 ```rust
 use doe::*;
command!("ls -la");
command!("dust");
command!("lsd");
 ```
## run a function once after a particularized delay(millis)
 ```rust
 use doe::*;
set_timeout!(||{
    println!("ok");
},3000);
 ```
## run a function after a particularized delay(millis) each run delay(millis)
 ```rust
 use doe::*;
duration_set_timeout!(||{
     println!("ok");
 },3000,1000); //from now delay 3000ms,each 1000ms run func()
 ```
## run a function repeatedly, beginning after some millis, then repeating continuously at the given interval.
 ```rust
 use doe::*;
set_interval!(||{
    println!("ok");
},3000);
 ```

## get current UTC-timestamp
 ```rust
 use doe::*;
 let t = utc_timestamp!();
 eprintln!("{}", t);
 ```
## get Local now
 ```rust
 use doe::*;
 let t = local_now!();
 eprintln!("{}", t);
 ```
## get Utc now
 ```rust
 use doe::*;
 let t = utc_now!();
 eprintln!("{}", t);
 ```
## 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 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);
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
