Skip to main content

rustlinqdemo1/
sequence_extensions.rs

1use std::collections::HashMap;
2
3use itertools::Itertools;
4
5/// Creates an owned sequence of consecutive `i32` values.
6pub trait RangeOwned {
7    /// Creates `count` values starting at `start`.
8    fn range_owned(start: i32, count: u32) -> Vec<i32>;
9}
10
11/// Provides the range-generation entry point.
12pub struct RangeGenerator;
13
14impl RangeOwned for RangeGenerator {
15    fn range_owned(start: i32, count: u32) -> Vec<i32> {
16        let mut result = Vec::new();
17
18        for i in start..start + (count as i32) {
19            result.push(i);
20        }
21        return result;
22    }
23}
24
25/// Provides an owned reverse-order copy of a sequence.
26pub trait ReverseOwned {
27    type Item;
28
29    /// Returns the items in reverse order without changing the source vector.
30    fn reverse_owned(&self) -> Vec<Self::Item>;
31}
32
33impl<T> ReverseOwned for Vec<T>
34where
35    T: Clone,
36{
37    type Item = T;
38
39    fn reverse_owned(&self) -> Vec<T> {
40        self.iter().rev().cloned().collect()
41    }
42}
43
44/// Provides a predicate that checks whether at least one item matches.
45pub trait Any {
46    type Item;
47
48    /// Returns true when any item matches the predicate.
49    fn any<F>(&self, predicate: F) -> bool
50    where
51        F: FnMut(&Self::Item) -> bool;
52}
53
54impl<T> Any for [T] {
55    type Item = T;
56
57    fn any<F>(&self, predicate: F) -> bool
58    where
59        F: FnMut(&Self::Item) -> bool,
60    {
61        self.iter().any(predicate)
62    }
63}
64
65/// Provides a predicate that checks whether every item matches.
66pub trait All {
67    type Item;
68
69    /// Returns true when all items match the predicate.
70    fn all<F>(&self, predicate: F) -> bool
71    where
72        F: FnMut(&Self::Item) -> bool;
73}
74
75impl<T> All for [T] {
76    type Item = T;
77
78    fn all<F>(&self, predicate: F) -> bool
79    where
80        F: FnMut(&Self::Item) -> bool,
81    {
82        self.iter().all(predicate)
83    }
84}
85
86/// Provides indexed lookup with a default value when the index is out of range.
87pub trait ElementAtOrDefault {
88    type Item;
89
90    /// Returns the item at `index`, or `T::default()` when no item exists there.
91    fn elementat_or_default(&self, index: usize) -> Self::Item;
92}
93
94impl<T> ElementAtOrDefault for [T]
95where
96    T: Default + Clone,
97{
98    type Item = T;
99
100    fn elementat_or_default(&self, index: usize) -> Self::Item {
101        self.get(index).cloned().unwrap_or_default()
102    }
103}
104
105/// Provides first-item lookup with a default value for an empty sequence.
106pub trait FirstOrDefault {
107    type Item;
108
109    /// Returns the first item or the default value.
110    fn first_or_default(&self) -> Self::Item;
111}
112
113impl<T> FirstOrDefault for [T]
114where
115    T: Default + Clone,
116{
117    type Item = T;
118
119    fn first_or_default(&self) -> T {
120        self.first().cloned().unwrap_or_default()
121    }
122}
123
124/// Provides last-item lookup with a default value for an empty sequence.
125pub trait LastOrDefault {
126    type Item;
127
128    /// Returns the last item or the default value.
129    fn last_or_default(&self) -> Self::Item;
130}
131
132impl<T> LastOrDefault for [T]
133where
134    T: Default + Clone,
135{
136    type Item = T;
137
138    fn last_or_default(&self) -> T {
139        self.last().cloned().unwrap_or_default()
140    }
141}
142
143/// Returns a borrowed start of a slice, defined by a given size of number of items to take
144/// Provides borrowed views over the beginning of a slice.
145pub trait TakeRef {
146    type Item;
147
148    /// Returns up to n items from the start of the slice.
149    fn take_ref(&self, n: usize) -> &[Self::Item];
150}
151
152impl<T> TakeRef for [T] {
153    type Item = T;
154
155    fn take_ref(&self, n: usize) -> &[T] {
156        &self[..n.min(self.len())]
157    }
158}
159
160/// Returns an owned slice of the start of a vector.
161/// Provides owned start of the provided vector.
162pub trait TakeOwned {
163    type Item;
164
165    /// Returns up to n items from the start of the vector.
166    fn take_owned(self, n: usize) -> Vec<Self::Item>;
167}
168
169impl<T> TakeOwned for Vec<T> {
170    type Item = T;
171
172    fn take_owned(self, n: usize) -> Vec<Self::Item> {
173        let len = self.len();
174        self.into_iter().take(n.min(len)).collect()
175    }
176}
177
178// Provides skipped slice by n items that returns the rest of the vector
179pub trait SkipOwned {
180    type Item;
181
182    fn skip_owned(self, n: usize) -> Vec<Self::Item>;
183}
184
185impl<T> SkipOwned for Vec<T> {
186    type Item = T;
187
188    fn skip_owned(self, n: usize) -> Vec<Self::Item> {
189        self.into_iter().skip(n).collect()
190    }
191}
192
193/// Provides owned subsequences by consuming a vector.
194pub trait SkipTakeOwned {
195    type Item;
196
197    /// Returns up to n items after skipping m items.
198    fn skip_take_owned(self, m: usize, n: usize) -> Vec<Self::Item>;
199}
200
201impl<T> SkipTakeOwned for Vec<T> {
202    type Item = T;
203
204    fn skip_take_owned(self, m: usize, n: usize) -> Vec<Self::Item> {
205        let len = self.len();
206        self.into_iter().skip(m.min(len)).take(n.min(len)).collect()
207    }
208}
209
210/// Groups items into owned vectors keyed by a selector result.
211pub trait GroupByOwned {
212    type Item;
213
214    /// Consumes the vector and groups its items by `key_selector`.
215    fn group_by_owned<F, K>(self, key_selector: F) -> HashMap<K, Vec<Self::Item>>
216    where
217        F: FnMut(&Self::Item) -> K,
218        K: std::hash::Hash + Eq;
219}
220
221impl<T> GroupByOwned for Vec<T> {
222    type Item = T;
223
224    fn group_by_owned<F, K>(self, key_selector: F) -> std::collections::HashMap<K, Vec<T>>
225    where
226        F: FnMut(&T) -> K,
227        K: std::hash::Hash + Eq,
228    {
229        self.into_iter().into_group_map_by(key_selector)
230    }
231}