├── .gitignore ├── Cargo.toml ├── examples └── demo.rs ├── readme.dev.md ├── readme.md └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "construct" 4 | version = "0.0.3" 5 | authors = ["Ty Overby "] 6 | license = "MIT" 7 | repository = "https://github.com/TyOverby/construct" 8 | description = "A macro for building container literals." 9 | -------------------------------------------------------------------------------- /examples/demo.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate construct; 3 | 4 | use std::collections::HashMap; 5 | 6 | fn main() { 7 | // Vector construction 8 | let v = construct!(Vec<_>, 1,2,3,4); 9 | assert_eq!(v, vec![1,2,3,4]); 10 | 11 | 12 | // Hashmap construction 13 | let m = construct!(HashMap<_,_>, (1, "hi"), (2, "bye")); 14 | 15 | let mut manual = HashMap::new(); 16 | manual.insert(1, "hi"); 17 | manual.insert(2, "bye"); 18 | assert_eq!(m, manual); 19 | } 20 | -------------------------------------------------------------------------------- /readme.dev.md: -------------------------------------------------------------------------------- 1 | # Construct 2 | 3 | The `vec!` macro is pretty great, but it does only create `Vec`s. The 4 | `construct!` macro works for any type that implements `iter::Extend`, which 5 | is basically every collection! 6 | 7 | ## Install 8 | 9 | **Cargo.toml** 10 | 11 | ``` 12 | [dependencies] 13 | construct = "*" 14 | ``` 15 | 16 | ## Example 17 | 18 | ^code(./examples/demo.rs) 19 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Construct 2 | 3 | The `vec!` macro is pretty great, but it does only create `Vec`s. The 4 | `construct!` macro works for any type that implements `iter::Extend`, which 5 | is basically every collection! 6 | 7 | ## Install 8 | 9 | **Cargo.toml** 10 | 11 | ``` 12 | [dependencies] 13 | construct = "*" 14 | ``` 15 | 16 | ## Example 17 | 18 | ```rust 19 | #[macro_use] 20 | extern crate construct; 21 | 22 | use std::collections::HashMap; 23 | 24 | fn main() { 25 | // Vector construction 26 | let v = construct!(Vec<_>, 1,2,3,4); 27 | assert_eq!(v, vec![1,2,3,4]); 28 | 29 | 30 | // Hashmap construction 31 | let m = construct!(HashMap<_,_>, (1, "hi"), (2, "bye")); 32 | 33 | let mut manual = HashMap::new(); 34 | manual.insert(1, "hi"); 35 | manual.insert(2, "bye"); 36 | assert_eq!(m, manual); 37 | } 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(unstable)] 2 | 3 | pub struct ReserveN { 4 | pub n: usize 5 | } 6 | 7 | impl Iterator for ReserveN { 8 | type Item = T; 9 | 10 | fn next(&mut self) -> Option { 11 | None 12 | } 13 | 14 | fn size_hint(&self) -> (usize, Option) { 15 | (self.n, Some(self.n)) 16 | } 17 | } 18 | 19 | pub struct Single { 20 | t: Option 21 | } 22 | 23 | impl Single { 24 | pub fn new(t: T) -> Single { 25 | Single {t: Some(t)} 26 | } 27 | } 28 | 29 | impl Iterator for Single { 30 | type Item = T; 31 | 32 | fn next(&mut self) -> Option { 33 | self.t.take() 34 | } 35 | 36 | fn size_hint(&self) -> (usize, Option) { 37 | let s = match self.t { 38 | Some(_) => 1, 39 | None => 0 40 | }; 41 | (s, Some(s)) 42 | } 43 | } 44 | 45 | #[macro_export] 46 | macro_rules! construct { 47 | // HACK HACK HACK 48 | (COUNT,) => { 0 }; 49 | (COUNT, $first: expr) => { 1 }; 50 | (COUNT, $first: expr, $($rest: expr),+) => { 51 | 1 + construct!(COUNT, $($rest),+) 52 | }; 53 | 54 | ($t: ty, $($elems: expr ),*) => { 55 | { 56 | use std::iter::Extend; 57 | use std::default::Default; 58 | 59 | let size = construct!(COUNT, $($elems),*); 60 | 61 | let mut coll: $t = Default::default(); 62 | coll.extend($crate::ReserveN{n: size}); 63 | $(coll.extend($crate::Single::new($elems));)* 64 | coll 65 | } 66 | }; 67 | } 68 | 69 | #[cfg(test)] 70 | mod test { 71 | use std::collections::hash_map::HashMap; 72 | 73 | #[test] fn test_count() { 74 | assert_eq!(construct!(COUNT, 1,2,3,4), 4); 75 | assert_eq!(construct!(COUNT,), 0); 76 | assert_eq!(construct!(COUNT, 2), 1); 77 | } 78 | 79 | #[test] fn test_vec() { 80 | let v = construct!(Vec<_>, 1,2,3,4); 81 | assert_eq!(v, vec![1,2,3,4]); 82 | } 83 | 84 | #[test] fn test_map() { 85 | let m = construct!(HashMap<_,_>, (1, "hi"), (2, "bye")); 86 | 87 | let mut manual = HashMap::new(); 88 | manual.insert(1, "hi"); 89 | manual.insert(2, "bye"); 90 | assert_eq!(m, manual); 91 | } 92 | } 93 | --------------------------------------------------------------------------------