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}