map_macro/_std.rs
1/// Macro for creating a [`HashMap`](::std::collections::HashMap).
2///
3/// Syntactic sugar for [`HashMap::from`](::std::collections::HashMap::from).
4///
5/// # Examples
6///
7/// ```rust
8/// use map_macro::hash_map;
9///
10/// let goodbye = hash_map! {
11/// "en" => "Goodbye",
12/// "de" => "Auf Wiedersehen",
13/// "fr" => "Au revoir",
14/// "es" => "Adios",
15/// "cat" => "Adéu",
16/// };
17/// ```
18///
19#[macro_export]
20macro_rules! hash_map {
21 {$($k: expr => $v: expr),* $(,)?} => {
22 ::std::collections::HashMap::from([$(($k, $v),)*])
23 };
24}
25
26/// Explicitly typed equivalent of [`hash_map!`].
27///
28/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
29///
30/// # Examples
31///
32/// ```rust
33/// use std::collections::HashMap;
34/// use std::fmt::Debug;
35///
36/// use map_macro::hash_map_e;
37///
38/// let goodbye: HashMap<&str, &dyn Debug> = hash_map_e! {
39/// "en" => &"Goodbye",
40/// "de" => &"Auf Wiedersehen",
41/// "fr" => &"Au revoir",
42/// "es" => &"Adios",
43/// "cat" => &"Adéu",
44/// };
45///
46/// println!("{:?}", goodbye);
47/// ```
48///
49#[macro_export]
50macro_rules! hash_map_e {
51 {$($k: expr => $v: expr),* $(,)?} => {
52 ::std::collections::HashMap::from([$(($k as _, $v as _),)*])
53 };
54}
55
56/// Macro for creating a [`BTreeMap`](::std::collections::BTreeMap).
57///
58/// Syntactic sugar for [`BTreeMap::from`](::std::collections::BTreeMap::from).
59///
60/// # Examples
61///
62/// ```rust
63/// use map_macro::btree_map;
64///
65/// let goodbye = btree_map! {
66/// "en" => "Goodbye",
67/// "de" => "Auf Wiedersehen",
68/// "fr" => "Au revoir",
69/// "es" => "Adios",
70/// "cat" => "Adéu",
71/// };
72/// ```
73///
74#[macro_export]
75macro_rules! btree_map {
76 {$($k: expr => $v: expr),* $(,)?} => {
77 ::std::collections::BTreeMap::from([$(($k, $v),)*])
78 };
79}
80
81/// Explicitly typed equivalent of [`btree_map!`].
82///
83/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
84///
85/// # Examples
86///
87/// ```rust
88/// use std::collections::BTreeMap;
89/// use std::fmt::Debug;
90///
91/// use map_macro::btree_map_e;
92///
93/// let goodbye: BTreeMap<&str, &dyn Debug> = btree_map_e! {
94/// "en" => &"Goodbye",
95/// "de" => &"Auf Wiedersehen",
96/// "fr" => &"Au revoir",
97/// "es" => &"Adios",
98/// "cat" => &"Adéu",
99/// };
100/// ```
101///
102#[macro_export]
103macro_rules! btree_map_e {
104 {$($k: expr => $v: expr),* $(,)?} => {
105 ::std::collections::BTreeMap::from([$(($k as _, $v as _),)*])
106 };
107}
108
109/// Macro for creating a [`HashSet`](::std::collections::HashSet).
110///
111/// Syntactic sugar for [`HashSet::from`](::std::collections::HashSet::from).
112///
113/// # Examples
114///
115/// ```rust
116/// use map_macro::hash_set;
117///
118/// let x = hash_set! { 1, 2, 3, 3, 4 };
119///
120/// assert_eq!(x.len(), 4);
121/// ```
122///
123#[macro_export]
124macro_rules! hash_set {
125 {$($v: expr),* $(,)?} => {
126 ::std::collections::HashSet::from([$($v,)*])
127 };
128}
129
130/// Explicitly typed equivalent of [`hash_set!`].
131///
132/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
133///
134/// # Examples
135///
136/// ```rust
137/// use std::collections::HashSet;
138///
139/// use map_macro::hash_set_e;
140///
141/// enum Foo { A, B, C, D }
142///
143/// let x: HashSet<u8> = hash_set_e! { Foo::A, Foo::B, Foo::C, Foo::C, Foo::D };
144///
145/// assert_eq!(x.len(), 4);
146/// ```
147///
148#[macro_export]
149macro_rules! hash_set_e {
150 {$($v: expr),* $(,)?} => {
151 ::std::collections::HashSet::from([$($v as _,)*])
152 };
153}
154
155/// Macro for creating a [`BTreeSet`](::std::collections::BTreeSet).
156///
157/// Syntactic sugar for [`BTreeSet::from`](::std::collections::BTreeSet::from).
158///
159/// # Examples
160///
161/// ```rust
162/// use map_macro::btree_set;
163///
164/// let x = btree_set! { 1, 2, 3, 3, 4 };
165///
166/// assert_eq!(x.len(), 4);
167/// ```
168///
169#[macro_export]
170macro_rules! btree_set {
171 {$($v: expr),* $(,)?} => {
172 ::std::collections::BTreeSet::from([$($v,)*])
173 };
174}
175
176/// Explicitly typed equivalent of [`btree_set!`].
177///
178/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
179///
180/// # Examples
181///
182/// ```rust
183/// use std::collections::BTreeSet;
184///
185/// use map_macro::btree_set_e;
186///
187/// enum Foo { A, B, C, D }
188///
189/// let x: BTreeSet<u8> = btree_set_e! { Foo::A, Foo::B, Foo::C, Foo::C, Foo::D };
190///
191/// assert_eq!(x.len(), 4);
192/// ```
193///
194#[macro_export]
195macro_rules! btree_set_e {
196 {$($v: expr),* $(,)?} => {
197 ::std::collections::BTreeSet::from([$($v as _,)*])
198 };
199}
200
201/// Macro for creating a [`VecDeque`](::std::collections::VecDeque).
202///
203/// Follows the same syntax as the [`vec!`](::std::vec!) macro.
204///
205/// # Examples
206///
207/// ```
208/// use map_macro::vec_deque;
209///
210/// let v = vec_deque![0, 1, 2, 3];
211/// let v = vec_deque![0; 4];
212/// ```
213///
214#[macro_export]
215macro_rules! vec_deque {
216 {$v: expr; $c: expr} => {
217 {
218 let mut vec = ::std::collections::VecDeque::with_capacity($c);
219
220 for _ in 0..$c {
221 vec.push_back($v);
222 }
223
224 vec
225 }
226 };
227 {$($v: expr),* $(,)?} => {
228 ::std::collections::VecDeque::from([$($v,)*])
229 };
230}
231
232/// Explicitly typed equivalent of [`vec_deque!`].
233///
234/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
235///
236/// # Examples
237///
238/// ```
239/// use std::collections::VecDeque;
240/// use std::fmt::Debug;
241///
242/// use map_macro::vec_deque_e;
243///
244/// let v: VecDeque<&dyn Debug> = vec_deque_e![&0, &1, &2, &3];
245/// let v: VecDeque<&dyn Debug> = vec_deque_e![&0; 4];
246/// ```
247///
248#[macro_export]
249macro_rules! vec_deque_e {
250 {$v: expr; $c: expr} => {
251 {
252 let mut vec = ::std::collections::VecDeque::with_capacity($c);
253
254 for _ in 0..$c {
255 vec.push_back($v as _);
256 }
257
258 vec
259 }
260 };
261 {$($v: expr),* $(,)?} => {
262 ::std::collections::VecDeque::from([$($v as _,)*])
263 };
264}
265
266/// Macro for creating a [`LinkedList`](::std::collections::LinkedList).
267///
268/// Follows the same syntax as the [`vec!`](::std::vec!) macro.
269///
270/// # Examples
271///
272/// ```
273/// use map_macro::linked_list;
274///
275/// let v = linked_list![0, 1, 2, 3];
276/// let v = linked_list![0; 4];
277/// ```
278///
279#[macro_export]
280macro_rules! linked_list {
281 {$v: expr; $c: expr} => {
282 {
283 let mut ll = ::std::collections::LinkedList::new();
284
285 for _ in 0..$c {
286 ll.push_back($v);
287 }
288
289 ll
290 }
291 };
292 {$($v: expr),* $(,)?} => {
293 ::std::collections::LinkedList::from([$($v,)*])
294 };
295}
296
297/// Explicitly typed equivalent of [`linked_list!`].
298///
299/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
300///
301/// # Examples
302///
303/// ```
304/// use std::collections::LinkedList;
305/// use std::fmt::Debug;
306///
307/// use map_macro::linked_list_e;
308///
309/// let v: LinkedList<&dyn Debug> = linked_list_e![&0, &1, &2, &3];
310/// let v: LinkedList<&dyn Debug> = linked_list_e![&0; 4];
311/// ```
312///
313#[macro_export]
314macro_rules! linked_list_e {
315 {$v: expr; $c: expr} => {
316 {
317 let mut ll = ::std::collections::LinkedList::new();
318
319 for _ in 0..$c {
320 ll.push_back($v as _);
321 }
322
323 ll
324 }
325 };
326 {$($v: expr),* $(,)?} => {
327 ::std::collections::LinkedList::from([$($v as _,)*])
328 };
329}
330
331/// Macro for creating a [`BinaryHeap`](::std::collections::BinaryHeap).
332///
333/// Follows the same syntax as the [`vec!`](::std::vec!) macro.
334///
335/// # Examples
336///
337/// ```
338/// use map_macro::binary_heap;
339///
340/// let v = binary_heap![0, 1, 2, 3];
341/// let v = binary_heap![0; 4];
342/// ```
343///
344#[macro_export]
345macro_rules! binary_heap {
346 {$v: expr; $c: expr} => {
347 {
348 let mut bh = ::std::collections::BinaryHeap::with_capacity($c);
349
350 for _ in 0..$c {
351 bh.push($v);
352 }
353
354 bh
355 }
356 };
357 {$($v: expr),* $(,)?} => {
358 ::std::collections::BinaryHeap::from([$($v,)*])
359 };
360}
361
362/// Explicitly typed equivalent of [`binary_heap!`].
363///
364/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
365///
366/// # Examples
367///
368/// ```
369/// use std::collections::BinaryHeap;
370///
371/// use map_macro::binary_heap_e;
372///
373/// enum Foo { A, B, C, D }
374///
375/// let v: BinaryHeap<u8> = binary_heap_e![Foo::A, Foo::B, Foo::C, Foo::D];
376/// let v: BinaryHeap<u8> = binary_heap_e![Foo::A; 4];
377/// ```
378///
379#[macro_export]
380macro_rules! binary_heap_e {
381 {$v: expr; $c: expr} => {
382 {
383 let mut bh = ::std::collections::BinaryHeap::with_capacity($c);
384
385 for _ in 0..$c {
386 bh.push($v as _);
387 }
388
389 bh
390 }
391 };
392 {$($v: expr),* $(,)?} => {
393 ::std::collections::BinaryHeap::from([$($v as _,)*])
394 };
395}
396
397/// Version of the [`vec!`](::std::vec!) macro where the value does not have to implement [`Clone`].
398///
399/// Useful for unclonable types or where `Clone` is exerting undesired behaviour.
400///
401/// # Uncloneable Types
402///
403/// When using `vec![x; count]`, the type of `x` has to implement `Clone`, because
404/// `x` is cloned `count - 1` times into all the vector elements except the first one.
405/// For example, calling `vec!` will result in a panic during compile time here,
406/// because `UnclonableWrapper` is not cloneable:
407///
408/// ```compile_fail
409/// struct UnclonableWrapper(u8);
410///
411/// let x = vec![UnclonableWrapper(0); 5];
412/// ```
413///
414/// The `vec_no_clone!` macro takes a different approach.
415/// Instead of cloning `UnclonableWrapper(0)`, it treats it as an
416/// [expression](https://doc.rust-lang.org/reference/expressions.html) which is
417/// called 5 times in this case.
418/// So 5 independent `UnclonableWrapper` objects, each with its own location in
419/// memory, are created:
420///
421/// ```rust
422/// use map_macro::vec_no_clone;
423///
424/// struct UnclonableWrapper(u8);
425///
426/// let x = vec_no_clone![UnclonableWrapper(0); 5];
427///
428/// assert_eq!(x.len(), 5);
429/// ```
430///
431/// A real-world example where `vec_no_clone!` is a useful drop-in replacement
432/// for `vec!` are [atomic types](::std::sync::atomic), which are not clonable:
433///
434/// ```rust
435/// use std::sync::atomic::AtomicU8;
436///
437/// use map_macro::vec_no_clone;
438///
439/// let x = vec_no_clone![AtomicU8::new(0); 5];
440///
441/// assert_eq!(x.len(), 5);
442/// ```
443///
444/// # Types where `Clone` exerts the wrong Behaviour
445///
446/// `vec_no_clone!` is not only useful for unclonable types, but also for types
447/// where cloning them is not what you want.
448/// The best example would be a reference counted pointer [`Rc`](::std::rc::Rc).
449/// When you clone an `Rc`, a new instance referencing the same location in memory
450/// is created.
451/// If you'd rather have multiple independent reference counted pointers to
452/// different memory locations, you can use `vec_no_clone!` as well:
453///
454/// ```rust
455/// use map_macro::vec_no_clone;
456///
457/// use std::cell::RefCell;
458/// use std::rc::Rc;
459///
460/// // simply clones the reference counted pointer for each element that
461/// // is not the first
462/// let shared_vec = vec![Rc::new(RefCell::new(0)); 2];
463/// {
464/// let mut first = shared_vec[0].borrow_mut();
465/// *first += 1;
466/// }
467///
468/// assert_eq!(*shared_vec[0].borrow(), 1);
469///
470/// // the second element is a clone of the reference counted pointer at
471/// // the first element of the vector, referencing the same address in
472/// // memory, therefore being mutated as well
473/// assert_eq!(*shared_vec[1].borrow(), 1);
474///
475/// // the `vec_no_clone!` macro does not clone the object created by the
476/// // first expression but instead calls the expression for each element
477/// // in the vector, creating two independent objects, each with their
478/// // own address in memory
479/// let unshared_vec = vec_no_clone![Rc::new(RefCell::new(0)); 2];
480///
481/// {
482/// let mut first = unshared_vec[0].borrow_mut();
483/// *first += 1;
484/// }
485///
486/// assert_eq!(*unshared_vec[0].borrow(), 1);
487///
488/// // the second element is not the same cloned reference counted
489/// // pointer as it would be if it were constructed with the `vec!` macro
490/// // from the standard library like it was above, therefore it is not
491/// // mutated
492/// assert_eq!(*unshared_vec[1].borrow(), 0);
493/// ```
494///
495/// # Drawbacks of using Expressions
496///
497/// Since `vec_no_clone!` treats the value as an expression, you must provide the
498/// initialization as input directly.
499/// This, for example, won't work:
500///
501/// ```compile_fail
502/// use map_macro::vec_no_clone;
503///
504/// struct UnclonableWrapper(u8);
505///
506/// let a = UnclonableWrapper(0);
507///
508/// // a will have moved into the first element of x, raising a compile
509/// // time error for the second element.
510/// let x = vec_no_clone![a; 5];
511/// ```
512///
513/// # Processing Lists of Elements
514///
515/// You can also use the macro with a list of elements, like `vec!`.
516/// In fact, `vec_no_clone!` falls back to `vec!` in this case:
517///
518/// ```rust
519/// use map_macro::vec_no_clone;
520///
521/// let v1 = vec_no_clone![0, 1, 2, 3];
522/// let v2 = vec![0, 1, 2, 3];
523///
524/// assert_eq!(v1, v2);
525///
526/// let v1: Vec<u8> = vec_no_clone![];
527/// let v2: Vec<u8> = vec![];
528///
529/// assert_eq!(v1, v2);
530/// ```
531///
532#[macro_export]
533macro_rules! vec_no_clone {
534 {$v: expr; $c: expr} => {
535
536 {
537 let mut vec = Vec::with_capacity($c);
538
539 for _ in 0..$c {
540 vec.push($v);
541 }
542
543 vec
544 }
545 };
546 {$($v: expr),* $(,)?} => {
547 {
548 vec![$($v),*]
549 }
550 };
551}
552
553/// Explicitly typed equivalent of [`vec_no_clone!`].
554///
555/// See the [explicity typed macros](crate#explicitly-typed-macros) section.
556///
557/// # Examples
558///
559/// ```
560/// use std::fmt::Display;
561///
562/// use map_macro::vec_no_clone_e;
563///
564/// let v: Vec<&dyn Display> = vec_no_clone_e![&0; 4];
565/// ```
566///
567#[macro_export]
568macro_rules! vec_no_clone_e {
569 {$v: expr; $c: expr} => {
570
571 {
572 let mut vec = Vec::with_capacity($c);
573
574 for _ in 0..$c {
575 vec.push($v as _);
576 }
577
578 vec
579 }
580 };
581 {$($v: expr),* $(,)?} => {
582 {
583 vec![$($v as _),*]
584 }
585 };
586}