doe


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
ctf
cargo add doe -F ctf
allow you to perform various operations with ease, such as string manipulation, urlencode urldecode,hex encode decode,base43 encode decode, and error management.
http
cargo add doe -F http
simplifies reqwest HTTP requests, allowing you to effortlessly send and receive data from remote servers.
clip
cargo add doe -F clip
simplifies clipboard management, enabling you to effortlessly interact with the system clipboard.
mouse
cargo add doe -F mouse
offers intuitive and easy-to-use functions for simulating mouse actions.
keyboard
cargo add doe -F keyboard
offers simulating keyboard input action with easy-to-use functions.
kcm
kcm is short feature for keyboard clipboard mouse together
cargo add doe -F kcm
xlsx
read edit write xlsx file
cargo add doe -F xlsx
docx
read edit docx file
cargo add doe -F docx
date
get and read edit date string
cargo add doe -F date
screenshot
screenshot and get hex from screenshot image
cargo add doe -F screenshot
images
resize add paddings,convert image format
cargo add doe -F images
crypto
crypto module contains AES,RSA,sha1,sha2,sha3,md5,blake3 functions
AES with mode:
CBC
CFB
CTR
ECB
IGE
OFB
cargo add doe -F crypto
Examples
crypto example
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
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"];
move_to_press_left(857, 588).sleep(1.0);
move_to_paste(1540, 853, "Apple").sleep(1.0); move_to_paste(1360, 882, "ID").sleep(1.0);
move_to_paste(772, 464, "Discription").sleep(1.0); mouse_drag((894, 719).into(), (821, 716).into()).sleep(1.0); key_click("2024-01-23").sleep(1.0);
move_to_press_left(740, 305).sleep(1.0);
for name in list {
move_to_press_left(476, 253).sleep(1.0);
move_to_press_left(796, 331).sleep(1.0); key_click("end");
key_click("shift+home");
set_clipboard(name).unwrap().sleep(0.5);
key_click("ctrl+v");
move_to_press_left(870, 587).sleep(1.0); mouse_drag((893, 818).into(), (814, 816).into()).sleep(1.0); key_click("2024-01-23").sleep(1.0);
move_to_press_left(723, 206).sleep(1.0); }
move_to_paste(1341, 910, "New_name").sleep(1.0);
docx_replace
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
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
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
fn main(){
use doe::mouse::listen_all;
listen_all();
}
run to generate script
cargo r > 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);
run script
use doe::mouse::automater;
let script = include_str!("../script.m");
automater(script);
mouse automater
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
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
keyboard example
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_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"]
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
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
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)); f2.call().println();
}
implments Bts struct and bts! macro for Box<dyn ToString> trait object
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(); s.as_bytes().println(); s.chars().println(); let b = Into::<Bts>::into("b".to_string());
let b = Bts::from("demo");
}
implmemt Debug,Display,Clone,Default,Drop trait for Struct
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
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 {d},I like Trait Object {p}}%"
.format(targets!{"{d}"=>"demo","{p}"=>100})
.println(); }
implment print println eprint eprintln for impl Display, impl Debug
use doe::Print;
use doe::DebugPrint;
"printable text".print();"printable text".println();
"printable text".eprintln();
#[derive(Debug)]
struct DebugPrintDemo{}let d = DebugPrintDemo{};
d.dprint();
d.dprintln();
d.deprintln();
implment targets! for return Vec<(Box<dyn ToString>,Box<dyn ToString>)>
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(); }
run timer by send stop_massge by channel
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
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(|| {
println!("Running...");
}),
);
}
});
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()>
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
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("demo.txt", "demo".as_bytes().to_vec()).unwrap();
walk_dir(".".to_path().deref()).unwrap().println();
walk_dir_get_files(".".to_path().deref()).unwrap().println();
walk_dir_get_folders(".".to_path().deref())
.unwrap()
.println();
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(
"/Users/ryanandrew/code/test/t1/demo.zip".to_path().deref(),
"/Users/ryanandrew/code/test/t2/d2.zip".to_path().deref(),
)
.unwrap();
move_folder(
"/Users/ryanandrew/code/test/t1".to_path().deref(),
"/Users/ryanandrew/code/test/t2/t1".to_path().deref(),
)
.unwrap();
copy_folder(
"/Users/ryanandrew/code/test/d1".to_path().deref(),
"/Users/ryanandrew/code/test/d2".to_path().deref(),
)
.unwrap();
}
like pythons os.system() function
pub fn run() {
system!("ping bing.com");
system_powershell!("ls");
system!("python -m http.server"); }
implment cut format for str and String
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
use doe::*;
let s = as_to!(5., i64);
assert_eq!(5, s);
if type is i8 return true
use doe::*;
assert_eq!(macros::is_i8(&5_i8),true);
if type is i16 return true
use doe::*;
assert_eq!(macros::is_i16(&5_i16),true);
if type is i32 return true
use doe::*;
assert_eq!(macros::is_i32(&5_i32),true);
if type is i64 return true
use doe::*;
assert_eq!(macros::is_i64(&5_i64),true);
if type is i128 return true
use doe::*;
assert_eq!(macros::is_i128(&5_i128),true);
if type is f32 return true
use doe::*;
assert_eq!(macros::is_f32(&5.0_f32),true);
if type is f64 return true
use doe::*;
assert_eq!(macros::is_f64(&5.0_f64),true);
returns a raised to the b power
use doe::*;
let p = powf!(2.,2.);
assert_eq!(p,4.0);
get argument and collect into Vec<String>
use doe::*;
let arg = args!();
assert_eq!(arg,vec![format!("-n"),format!("100")]);
get user input from terminal,return String
use doe::*;
let s = input!();
println!("{:?}",s);
Spliy &str by spliter and collect into Vec<String>
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>>
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
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
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>
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>
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)
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
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
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
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
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
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
remove_file_or_folder!("./demo.txt");
remove_file_or_folder!("./target");
get vec type ,return string type value
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
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
use doe::*;
let re_max = max!(1, 20);
assert_eq!(re_max,20);
expr return min value
use doe::*;
let re_min = min!(10, 2, 2, 5, 4, 6);
assert_eq!(re_min,2);
convert binary string to decimal
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
use doe::*;
let d1 = binary_to_decimal!("01101",i128);
println!("{:?}",memory_address!(d1));
Merge two Vec return merged 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);
take size of elements and return a new vec
use doe::*;
let v1 = vec_element_take!(vec![0, 1, 2],2);
assert_eq!(vec![0,1],v1);
zip two vec elements in tuple
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
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
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
use doe::*;
let v1 = has_nightly_compiler!();
assert_eq!(v1, true);
has stable rust compiler return bool
use doe::*;
let v1 = has_stable_compiler!();
assert_eq!(v1, false);
run command
use doe::*;
command!("ls -la");
command!("dust");
command!("lsd");
run a function once after a particularized delay(millis)
use doe::*;
set_timeout!(||{
println!("ok");
},3000);
run a function after a particularized delay(millis) each run delay(millis)
use doe::*;
duration_set_timeout!(||{
println!("ok");
},3000,1000);
run a function repeatedly, beginning after some millis, then repeating continuously at the given interval.
use doe::*;
set_interval!(||{
println!("ok");
},3000);
get current UTC-timestamp
use doe::*;
let t = utc_timestamp!();
eprintln!("{}", t);
get Local now
use doe::*;
let t = local_now!();
eprintln!("{}", t);
get Utc now
use doe::*;
let t = utc_now!();
eprintln!("{}", t);
macro for 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);
macro for 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);