pub use std::collections::HashMap;
pub use std::collections::HashSet;
#[macro_export]
macro_rules! count_args {
() => {
0usize
};
( $arg:expr ) => {
1usize
};
( $arg:expr, $( $rest:expr ),* ) => {
1usize + count_args!( $( $rest ),* )
};
}
#[macro_export]
macro_rules! string {
() => {
String::new()
};
( $arg:expr ) => {
String::from($arg)
};
}
#[macro_export]
macro_rules! concat_vec {
( $( $sliceable:expr ),* ) => {{
[
$(
&$sliceable[..],
)*
].concat()
}};
}
#[macro_export]
macro_rules! hashmap {
() => {
HashMap::new()
};
( $( $key:expr => $value:expr ),* ) => {{
let size = count_args!( $( $key ),* );
let mut map = HashMap::with_capacity(size);
$(
map.insert($key, $value);
)*
map
}};
}
#[macro_export]
macro_rules! hashset {
() => {
HashSet::new()
};
( $( $elem:expr ),* ) => {{
let size = count_args!( $($elem),* );
let mut set = HashSet::with_capacity(size);
$(
set.insert($elem);
)*
set
}};
}
#[macro_export]
macro_rules! sort {
( $collection:expr ) => {
(&mut $collection[..]).sort_unstable();
};
( $collection:expr, $compare_fn:expr ) => {
(&mut $collection[..]).sort_unstable_by($compare_fn);
};
}
#[macro_export]
macro_rules! sorted {
( $collection:expr ) => {{
let mut clones: Vec<_> = $collection.iter().cloned().collect();
sort!(clones);
clones
}};
( $collection:expr, $compare_fn:expr ) => {{
let mut clones: Vec<_> = $collection.iter().cloned().collect();
sort!(clones, $compare_fn);
clones
}};
}
#[macro_export]
macro_rules! sorted_f64 {
( $collection:expr ) => {
sorted!($collection, |a, b| a.partial_cmp(b).unwrap())
};
}
#[cfg(test)]
mod tests {
use super::*;
use std::cmp::Ordering::{Equal, Greater, Less};
mod count_args {
use super::*;
#[test]
fn zero() {
let expected = 0;
let result = count_args!();
assert_eq!(expected, result);
}
#[test]
fn one() {
let expected = 1;
let result = count_args!(10);
assert_eq!(expected, result);
}
#[test]
fn many() {
let expected = 4;
let result = count_args!(10, 20, 30, 40);
assert_eq!(expected, result);
}
}
mod concat_vec {
#[test]
fn one() {
let a = vec![1, 2];
let expected = vec![1, 2];
let result = concat_vec![a];
assert_eq!(expected, result);
}
#[test]
fn two() {
let a = vec![1, 2];
let b = vec![3, 4];
let expected = vec![1, 2, 3, 4];
let result = concat_vec![a, b];
assert_eq!(expected, result);
}
#[test]
fn many() {
let a = vec![1, 2];
let b = vec![3, 4];
let c = vec![5, 6];
let expected = vec![1, 2, 5, 6, 3, 4];
let result = concat_vec![a, c, b];
assert_eq!(expected, result);
}
}
mod hashmap {
use super::*;
#[test]
fn zero() {
let expected: HashMap<usize, usize> = HashMap::new();
let result: HashMap<usize, usize> = hashmap!();
assert_eq!(expected, result);
}
#[test]
fn one() {
let key = "abcde";
let expected: HashMap<String, usize> =
[(string!(key), 3usize)].iter().cloned().collect();
let result: HashMap<String, usize> = hashmap!(string!(key) => 3usize);
assert_eq!(expected, result);
}
#[test]
fn many() {
let expected: HashMap<String, usize> = vec![
(string!("a"), 10usize),
(string!("ab"), 20usize),
(string!("abc"), 30usize),
]
.into_iter()
.collect();
let result = hashmap!(
string!("a") => 10usize,
string!("ab") => 20usize,
string!("abc") => 30usize
);
assert_eq!(expected, result);
}
}
mod hashset {
use super::*;
#[test]
fn zero() {
let expected: HashSet<usize> = HashSet::new();
let result: HashSet<usize> = hashset!();
assert_eq!(expected, result);
}
#[test]
fn one() {
let name = string!("Jack");
let expected: HashSet<String> = vec![&name].into_iter().cloned().collect();
let result: HashSet<String> = hashset!(name);
assert_eq!(expected, result);
}
#[test]
fn many() {
let expected: HashSet<&str> = vec!["a", "b", "c"].into_iter().collect();
let result: HashSet<&str> = hashset!("a", "b", "c");
assert_eq!(expected, result);
}
}
mod sort {
use super::*;
#[test]
fn vec() {
let expected = vec![-14, -1, 0, 2, 3, 4, 8];
let mut v = vec![4, 2, 3, -1, -14, 0, 8];
sort!(v);
assert_eq!(expected, v);
}
#[test]
fn array() {
let expected = vec![-14, -1, 0, 2, 3, 4, 8];
let mut v = [4, 2, 3, -1, -14, 0, 8];
sort!(v);
assert_eq!(expected, v);
}
#[test]
fn vec_reverse_sort() {
let expected = vec![8, 4, 3, 2, 0, -1, -14];
let mut v = vec![4, 2, 3, -1, -14, 0, 8];
sort!(v, |a, b| match a.cmp(b) {
Less => Greater,
Greater => Less,
Equal => Equal,
});
assert_eq!(expected, v);
}
}
mod sorted {
use super::*;
#[test]
fn vec() {
let expected = vec![-14, -1, 0, 2, 3, 4, 8];
let v = vec![4, 2, 3, -1, -14, 0, 8];
let result = sorted!(v);
assert_eq!(expected, result);
assert_eq!(vec![-14, -1, 0, 2, 3, 4, 8], expected); }
#[test]
fn hashset() {
let expected = vec![-14, -1, 0, 2, 3, 4, 8];
let v = hashset![4, 2, 3, -1, -14, 0, 8];
let result = sorted!(v);
assert_eq!(expected, result);
}
#[test]
fn array() {
let expected = vec![-14, -1, 0, 2, 3, 4, 8];
let v = [4, 2, 3, -1, -14, 0, 8];
let result = sorted!(v);
assert_eq!(expected, result);
}
#[test]
fn vec_reverse_sort() {
let expected = vec![8, 4, 3, 2, 0, -1, -14];
let v = vec![4, 2, 3, -1, -14, 0, 8];
let result = sorted!(v, |a, b| match a.cmp(b) {
Less => Greater,
Greater => Less,
Equal => Equal,
});
assert_eq!(expected, result);
assert_eq!(vec![8, 4, 3, 2, 0, -1, -14], expected); }
}
mod sorted_f64 {
use super::*;
#[test]
fn vec() {
let expected = vec![-14.0, -1.0, 0.0, 2.0, 3.0, 4.0, 8.0];
let v = vec![4.0, 2.0, 3.0, -1.0, -14.0, 0.0, 8.0];
let result = sorted_f64!(v);
assert_eq!(expected, result);
}
#[test]
fn array() {
let expected = vec![-14.0, -1.0, 0.0, 2.0, 3.0, 4.0, 8.0];
let v = [4.0, 2.0, 3.0, -1.0, -14.0, 0.0, 8.0];
let result = sorted_f64!(v);
assert_eq!(expected, result);
}
}
}