#键盘输入 #剪贴板 #鼠标 #键盘 #状态管理 #鼠标输入 #

bin+lib doe

doe 是一个强大的 Rust 包,旨在通过提供大量有用的宏和实用函数来增强开发工作流程。它不仅简化了常见任务,还提供了方便的剪贴板管理、强大的加密函数、键盘输入和鼠标交互功能。

173 个版本 (36 个稳定版)

1.1.37 2024年8月21日
1.1.35 2024年7月29日
1.1.28 2024年6月29日
1.1.10 2024年3月11日
0.1.32 2022年11月5日

#49开发工具

Download history 51/week @ 2024-05-03 42/week @ 2024-05-10 67/week @ 2024-05-17 322/week @ 2024-05-24 59/week @ 2024-05-31 40/week @ 2024-06-07 50/week @ 2024-06-14 47/week @ 2024-06-21 450/week @ 2024-06-28 616/week @ 2024-07-05 73/week @ 2024-07-12 36/week @ 2024-07-19 420/week @ 2024-07-26 94/week @ 2024-08-02 37/week @ 2024-08-09 145/week @ 2024-08-16

704 每月下载量
用于 31 个包 (30 直接使用)

MIT 和可能 GPL-3.0-or-later

380KB
6.5K SLoC

doe

Crates.io Rust license

doe 是一个多功能的 Rust 包,通过提供大量有用的宏和实用函数,显著增强了开发工作流程。它简化了常见任务,并提供了方便的剪贴板管理、状态管理、键盘输入和鼠标交互功能。此外,doe 包含强大的加密函数,使开发者能够轻松地将安全的加密、解密和哈希功能集成到他们的应用程序中,确保数据的完整性和机密性。

功能

ctf

cargo add doe -F ctf

允许您轻松执行各种操作,例如字符串操作、urlencode urldecode、hex encode decode、base43 encode decode 和错误管理。

http

cargo add doe -F http

简化了 reqwest HTTP 请求,使您能够轻松地从远程服务器发送和接收数据。

clip

cargo add doe -F clip

简化了剪贴板管理,使您能够轻松地与系统剪贴板交互。

mouse

cargo add doe -F mouse

提供了直观且易于使用的函数来模拟鼠标操作。

keyboard

cargo add doe -F keyboard

提供了使用易于使用的函数模拟键盘输入操作的函数。

kcm

kcm 是键盘、剪贴板、鼠标的组合功能

cargo add doe -F kcm

xlsx

读取、编辑、写入 xlsx 文件

cargo add doe -F xlsx

docx

读取、编辑 docx 文件

cargo add doe -F docx

date

获取和读取、编辑日期字符串

cargo add doe -F date

screenshot

截图并从截图图像中获取十六进制值

cargo add doe -F screenshot

images

调整大小、添加填充、转换图像格式

cargo add doe -F images

crypto

crypto 模块包含 AES、RSA、sha1、sha2、sha3、md5、blake3 函数

AES 模式:CBC CFB CTR ECB IGE OFB

cargo add doe -F crypto

示例

crypto 示例

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));

键盘示例

// 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

//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 特性

use doe::*;
use doe::keyboard::exit_if_click_esc;
let t1 = run.spawn();
let t2 = exit_if_click_esc.spawn();
t1.join();
t2.join();

监听键盘和鼠标

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();
}

自动化

生成脚本

fn main(){
    use doe::mouse::listen_all;
    listen_all();
}

运行以生成脚本

cargor>script.m

script.m

 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);

运行脚本

 use doe::mouse::automater;
 let script =  include_str!("../script.m");
 automater(script);

鼠标自动化

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);
}

鼠标点击左键拖动

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");
}
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

键盘示例

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();
}

控制鼠标

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"]
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 是一个实现 Copy 特性的结构体

 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();

实现了 Bts 结构体和 bts! 宏,用于 Box<dyn Fn()> 特性对象

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();
}

实现了 Bts 结构体和 bts! 宏,用于 Box<dyn ToString> 特性对象

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");
}

为 Struct 实现了 Debug、Display、Clone、Default、Drop 特性

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);
}

为 impl ToString 实现了 format

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%
}

为 impl Display 和 impl Debug 实现了 print、println、eprint、eprintln

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();

为返回 Vec<(Box<dyn ToString>,Box<dyn ToString>)> 实现了 targets!

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%
}

通过发送消息通过通道来运行计时器,通过发送 stop_massge 消息来停止

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");
}

通过共享状态来运行计时器

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");

}

计时器参数::start_time:Instant,step_time:Duration,stop_time:Duration,func:Box<dyn Fn()>

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));

fs 模块的用法

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();
}

类似于 Python 的 os.system() 函数

pub fn run() {
    //linux and macos
    system!("ping bing.com");
    // in windows
    system_powershell!("ls");
    system!("python -m http.server"); //run in cmd
}

为 str 和 String 实现了 cut 格式

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);

类型转换

 use doe::*;
 let s = as_to!(5., i64);
 assert_eq!(5, s);

如果类型是 i8 返回 true

use doe::*;
assert_eq!(macros::is_i8(&5_i8),true);

如果类型是 i16 返回 true

use doe::*;
assert_eq!(macros::is_i16(&5_i16),true);

如果类型是 i32 返回 true

use doe::*;
assert_eq!(macros::is_i32(&5_i32),true);

如果类型是 i64 返回 true

use doe::*;
assert_eq!(macros::is_i64(&5_i64),true);

如果类型是 i128 返回 true

use doe::*;
assert_eq!(macros::is_i128(&5_i128),true);

如果类型是 f32 返回 true

use doe::*;
assert_eq!(macros::is_f32(&5.0_f32),true);

如果类型是 f64 返回 true

use doe::*;
assert_eq!(macros::is_f64(&5.0_f64),true);

返回 a 的 b 次幂

use doe::*;
let p = powf!(2.,2.);
assert_eq!(p,4.0);

获取参数并收集到 Vec<String>

use doe::*;
//cargo run -- -n 100
let arg = args!();
assert_eq!(arg,vec![format!("-n"),format!("100")]);

从终端获取用户输入,返回 String

use doe::*;
let s = input!();
println!("{:?}",s);

通过分隔符分割 &str 并收集到 Vec<String>

use doe::*;
let s = split_to_vec!("aa.bb",".");
assert_eq!(s,vec![format!("aa"),format!("bb")]);

读取 .csv 文件并将内容收集到 Vec<Vec<String>>

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")]]);

排序后的新 Vec

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]);

排序并去重后的 Vec

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]);

将 Vec 元素解析为类型,解析 Vec<&str> 并收集到 Vec<type>

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);

将 vec 元素转换为 String,返回 Vec<String>

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);

返回从最外层元素到中间元素,按顺时针方向(n x n)排列的数组元素

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);

乘以两个矩阵

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]]);

找到第一个元素并删除

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);

找到元素位置并收集到 Vec

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]);

按范围切片 vec

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()]);

按索引克隆元素

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!("./demo.txt");
remove_file_or_folder!("./target");

获取 vec 类型,返回字符串类型值

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>"));

转换 vec 元素类型

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 返回最大值

use doe::*;
let re_max = max!(1, 20);
assert_eq!(re_max,20);

expr 返回最小值

use doe::*;
let re_min = min!(10, 2, 2, 5, 4, 6);
assert_eq!(re_min,2);

将二进制字符串转换为十进制

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 返回内存地址

use doe::*;
let d1 = binary_to_decimal!("01101",i128);
println!("{:?}",memory_address!(d1));//0x7ffcac734f08

合并两个 Vec,返回合并后的 Vec

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);

获取元素的大小并返回一个新 vec

use doe::*;
let v1 = vec_element_take!(vec![0, 1, 2],2);
assert_eq!(vec![0,1],v1);

将两个 vec 元素组合成元组

use doe::*;
let v1 = vec_zip!(vec![0, 1, 2],vec![0, 1, 2]);
assert_eq!(vec![(0,0),(1,1),(2,2)],v1);

枚举所有索引和元素,收集到 vec 的元组中

use doe::*;
let v1 = vec_enumerate!(vec![12, 11, 20]);
assert_eq!(vec![(0,12),(1,11),(2,20)],v1);

排序 vec 并返回排序后的 vec

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);

检查 rust nightly 是否稳定返回 bool

use doe::*;
let v1 = has_nightly_compiler!();
assert_eq!(v1, true);

检查 rust 编译器是否稳定返回 bool

use doe::*;
let v1 = has_stable_compiler!();
assert_eq!(v1, false);

运行命令

use doe::*;
command!("ls -la");
command!("dust");
command!("lsd");

在特定延迟(毫秒)后运行一次函数

use doe::*;
set_timeout!(||{
   println!("ok");
},3000);

在特定延迟(毫秒)后运行函数,每次运行延迟(毫秒)

use doe::*;
duration_set_timeout!(||{
    println!("ok");
},3000,1000); //from now delay 3000ms,each 1000ms run func()

反复运行函数,开始于一些毫秒后,然后以给定的间隔连续重复。

use doe::*;
set_interval!(||{
   println!("ok");
},3000);

获取当前的 UTC 时间戳

use doe::*;
let t = utc_timestamp!();
eprintln!("{}", t);

获取本地现在时间

use doe::*;
let t = local_now!();
eprintln!("{}", t);

获取 Utc 现在时间

use doe::*;
let t = utc_now!();
eprintln!("{}", t);

HashMap 宏

 use doe::*;
 use std::collections::HashMap;
 let mut map:HashMap<i32,i32> = hashmap!();
 map.insert(0, 1);
 let map1 = hashmap!(2=>5,3=>4);

BTreeMap 宏

 use doe::*;
 use std::collections::BTreeMap;
 let mut map:BTreeMap<i32,i32> = btreemap!();
 map.insert(0, 1);
 let map1 = btreemap!(2=>5,3=>4);

依赖项

~0–42MB
~600K SLoC