range_set_blaze/
map_from_iter.rs

1use alloc::rc::Rc;
2
3use crate::union_iter_map::UnionIterMap;
4use crate::{Integer, RangeMapBlaze};
5use core::ops::RangeInclusive;
6
7// We create a RangeMapBlaze from an iterator of integers or integer ranges by
8// 1. turning them into a UnionIterMap (internally, it collects into intervals and sorts by start).
9// 2. Turning the SortedDisjointMap into a BTreeMap.
10impl<'a, T, V> FromIterator<(T, &'a V)> for RangeMapBlaze<T, V>
11where
12    T: Integer,
13    V: Eq + Clone + 'a,
14{
15    /// Create a [`RangeMapBlaze`] from an iterator of integers. Duplicates and out-of-order elements are fine.
16    ///
17    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
18    ///
19    /// # Examples
20    ///
21    /// ```
22    /// use range_set_blaze::RangeMapBlaze;
23    ///
24    /// let a0 = RangeMapBlaze::from_iter([(3, &"a"), (2, &"a"), (1, &"a"), (100, &"b"), (1, &"c")]);
25    /// let a1: RangeMapBlaze<i32, &str> = [(3, &"a"), (2, &"a"), (1, &"a"), (100, &"b"), (1, &"c")].into_iter().collect();
26    /// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
27    /// ```
28    fn from_iter<I>(iter: I) -> Self
29    where
30        I: IntoIterator<Item = (T, &'a V)>,
31    {
32        iter.into_iter().map(|(x, r)| (x..=x, r)).collect()
33    }
34}
35
36impl<'a, T, V> FromIterator<(RangeInclusive<T>, &'a V)> for RangeMapBlaze<T, V>
37where
38    T: Integer,
39    V: Eq + Clone,
40{
41    /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
42    /// Overlapping, out-of-order, and empty ranges are fine.
43    ///
44    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
45    ///
46    /// # Examples
47    ///
48    /// ```
49    /// use range_set_blaze::prelude::*;
50    ///
51    /// #[allow(clippy::reversed_empty_ranges)]
52    /// let a0 = RangeMapBlaze::from_iter([(1..=2, &"a"), (2..=2, &"b"), (-10..=-5, &"c"), (1..=0, &"d")]);
53    /// #[allow(clippy::reversed_empty_ranges)]
54    /// let a1: RangeMapBlaze<i32, &str> = [(1..=2, &"a"), (2..=2, &"b"), (-10..=-5, &"c"), (1..=0, &"d")].into_iter().collect();
55    /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
56    /// ```
57    fn from_iter<I>(iter: I) -> Self
58    where
59        I: IntoIterator<Item = (RangeInclusive<T>, &'a V)>,
60    {
61        let iter = iter.into_iter();
62        let union_iter_map: UnionIterMap<T, &V, _> = iter.collect();
63        Self::from_sorted_disjoint_map(union_iter_map)
64    }
65}
66
67impl<T: Integer, V: Eq + Clone> FromIterator<(RangeInclusive<T>, V)> for RangeMapBlaze<T, V> {
68    /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
69    /// Overlapping, out-of-order, and empty ranges are fine.
70    ///
71    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use range_set_blaze::RangeMapBlaze;
77    ///
78    /// #[allow(clippy::reversed_empty_ranges)]
79    /// let a0 = RangeMapBlaze::from_iter([(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")]);
80    /// #[allow(clippy::reversed_empty_ranges)]
81    /// let a1: RangeMapBlaze<i32, &str> = [(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")].into_iter().collect();
82    /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
83    /// ```
84    fn from_iter<I>(iter: I) -> Self
85    where
86        I: IntoIterator<Item = (RangeInclusive<T>, V)>,
87    {
88        let union_iter_map = iter
89            .into_iter()
90            .map(|(r, v)| (r, Rc::new(v)))
91            .collect::<UnionIterMap<T, Rc<V>, _>>();
92        Self::from_sorted_disjoint_map(union_iter_map)
93    }
94}
95
96impl<T: Integer, V: Eq + Clone> FromIterator<(T, V)> for RangeMapBlaze<T, V> {
97    /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
98    /// Overlapping, out-of-order, and empty ranges are fine.
99    ///
100    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
101    ///
102    /// # Examples
103    ///
104    /// ```
105    /// use range_set_blaze::prelude::*;
106    ///
107    /// #[allow(clippy::reversed_empty_ranges)]
108    /// let a0 = RangeMapBlaze::from_iter([(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")]);
109    /// let a1: RangeMapBlaze<i32, &str> = [(3, "a"), (2, "a"), (1, "a"), (100, "b"), (1, "c")].into_iter().collect();
110    /// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
111    /// ```
112    fn from_iter<I>(iter: I) -> Self
113    where
114        I: IntoIterator<Item = (T, V)>,
115    {
116        iter.into_iter().map(|(k, v)| (k..=k, v)).collect()
117    }
118}
119
120impl<'a, T, V> FromIterator<&'a (T, &'a V)> for RangeMapBlaze<T, V>
121where
122    T: Integer,
123    V: Eq + Clone + 'a,
124{
125    /// Create a [`RangeMapBlaze`] from an iterator of integers. Duplicates and out-of-order elements are fine.
126    ///
127    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// use range_set_blaze::RangeMapBlaze;
133    ///
134    /// let v = vec![(3, &"a"), (2, &"a"), (1, &"a"), (100, &"b"), (1, &"c")];
135    /// let a0 = RangeMapBlaze::from_iter(&v);
136    /// let a1: RangeMapBlaze<i32, &str> = (&v).into_iter().collect();
137    /// assert!(a0 == a1 && a0.to_string() == r#"(1..=3, "a"), (100..=100, "b")"#);
138    /// ```
139    fn from_iter<I>(iter: I) -> Self
140    where
141        I: IntoIterator<Item = &'a (T, &'a V)>,
142    {
143        iter.into_iter().map(|&(x, r)| (x..=x, r)).collect()
144    }
145}
146
147impl<'a, T, V> FromIterator<&'a (RangeInclusive<T>, &'a V)> for RangeMapBlaze<T, V>
148where
149    T: Integer,
150    V: Eq + Clone,
151{
152    /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
153    /// Overlapping, out-of-order, and empty ranges are fine.
154    ///
155    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// use range_set_blaze::prelude::*;
161    ///
162    /// let v = vec![(1..=2, &"a"), (2..=2, &"b"), (-10..=-5, &"c"), (1..=0, &"d")];
163    /// let a0: RangeMapBlaze<i32, &str> = RangeMapBlaze::from_iter(&v);
164    /// let a1: RangeMapBlaze<i32, &str> = (&v).into_iter().collect();
165    /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
166    /// ```
167    fn from_iter<I>(iter: I) -> Self
168    where
169        I: IntoIterator<Item = &'a (RangeInclusive<T>, &'a V)>,
170    {
171        iter.into_iter().map(|(r, v)| (r.clone(), *v)).collect()
172    }
173}
174
175impl<'a, T: Integer, V: Eq + Clone> FromIterator<&'a (RangeInclusive<T>, V)>
176    for RangeMapBlaze<T, V>
177{
178    /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
179    /// Overlapping, out-of-order, and empty ranges are fine.
180    ///
181    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use range_set_blaze::prelude::*;
187    ///
188    /// #[allow(clippy::reversed_empty_ranges)]
189    /// let vec_range = vec![(1..=2, "a"), (2..=2, "b"), (-10..=-5, "c"), (1..=0, "d")];
190    /// let a0 = RangeMapBlaze::from_iter(&vec_range);
191    /// let a1: RangeMapBlaze<i32, &str> = vec_range.iter().collect();
192    /// assert!(a0 == a1 && a0.to_string() == r#"(-10..=-5, "c"), (1..=2, "a")"#);
193    /// ```
194    fn from_iter<I>(iter: I) -> Self
195    where
196        I: IntoIterator<Item = &'a (RangeInclusive<T>, V)>,
197    {
198        iter.into_iter().map(|(r, v)| (r.clone(), v)).collect()
199    }
200}
201
202impl<'a, T: Integer, V: Eq + Clone> FromIterator<&'a (T, V)> for RangeMapBlaze<T, V> {
203    /// Create a [`RangeMapBlaze`] from an iterator of inclusive ranges, `start..=end`.
204    /// Overlapping, out-of-order, and empty ranges are fine.
205    ///
206    /// *For more about constructors and performance, see [`RangeMapBlaze` Constructors](struct.RangeMapBlaze.html#rangemapblaze-constructors).*
207    ///
208    /// # Examples
209    ///
210    /// ```
211    /// use range_set_blaze::prelude::*;
212    ///
213    /// let v = vec![(1, "a"), (2, "a"), (2, "b")];
214    /// let a0 = RangeMapBlaze::from_iter(&v);
215    /// let a1: RangeMapBlaze<i32, &str> = v.iter().collect();
216    /// assert!(a0 == a1 && a0.to_string() == r#"(1..=2, "a")"#);
217    /// ```
218    fn from_iter<I>(iter: I) -> Self
219    where
220        I: IntoIterator<Item = &'a (T, V)>,
221    {
222        iter.into_iter()
223            .map(|(k, v)| {
224                let k = *k;
225                (k..=k, v)
226            })
227            .collect()
228    }
229}