Skip to main content

teaql_core/
list.rs

1use std::collections::BTreeMap;
2use std::hash::Hash;
3use std::ops::{Index, IndexMut};
4
5use crate::{Entity, IdentifiableEntity, Record, Value, VersionedEntity};
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct SmartList<T> {
9    pub data: Vec<T>,
10    pub total_count: Option<u64>,
11    pub aggregations: Record,
12    pub summary: Record,
13}
14
15impl<T> SmartList<T> {
16    pub fn empty() -> Self {
17        Self::new(Vec::new())
18    }
19
20    pub fn new(data: Vec<T>) -> Self {
21        Self {
22            data,
23            total_count: None,
24            aggregations: Record::new(),
25            summary: Record::new(),
26        }
27    }
28
29    pub fn with_total_count(mut self, total_count: u64) -> Self {
30        self.total_count = Some(total_count);
31        self
32    }
33
34    pub fn with_aggregation(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
35        self.aggregations.insert(key.into(), value.into());
36        self
37    }
38
39    pub fn with_summary(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
40        self.summary.insert(key.into(), value.into());
41        self
42    }
43
44    pub fn push(&mut self, value: T) {
45        self.data.push(value);
46    }
47
48    pub fn extend(&mut self, values: impl IntoIterator<Item = T>) {
49        self.data.extend(values);
50    }
51
52    pub fn set(&mut self, index: usize, value: T) -> Option<T> {
53        if index >= self.data.len() {
54            return None;
55        }
56        Some(std::mem::replace(&mut self.data[index], value))
57    }
58
59    pub fn get(&self, index: usize) -> Option<&T> {
60        self.data.get(index)
61    }
62
63    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
64        self.data.get_mut(index)
65    }
66
67    pub fn last(&self) -> Option<&T> {
68        self.data.last()
69    }
70
71    pub fn len(&self) -> usize {
72        self.data.len()
73    }
74
75    pub fn is_empty(&self) -> bool {
76        self.data.is_empty()
77    }
78
79    pub fn first(&self) -> Option<&T> {
80        self.data.first()
81    }
82
83    pub fn iter(&self) -> std::slice::Iter<'_, T> {
84        self.data.iter()
85    }
86
87    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
88        self.data.iter_mut()
89    }
90
91    pub fn as_slice(&self) -> &[T] {
92        &self.data
93    }
94
95    pub fn as_mut_slice(&mut self) -> &mut [T] {
96        &mut self.data
97    }
98
99    pub fn retain(&mut self, filter: impl FnMut(&T) -> bool) {
100        self.data.retain(filter);
101    }
102
103    pub fn total_count_or_len(&self) -> u64 {
104        self.total_count.unwrap_or(self.data.len() as u64)
105    }
106
107    pub fn aggregation(&self, key: &str) -> Option<&Value> {
108        self.aggregations.get(key)
109    }
110
111    pub fn summary(&self, key: &str) -> Option<&Value> {
112        self.summary.get(key)
113    }
114
115    pub fn aggregation_json(&self) -> serde_json::Value {
116        crate::record_to_json_value(&self.aggregations)
117    }
118
119    pub fn summary_json(&self) -> serde_json::Value {
120        crate::record_to_json_value(&self.summary)
121    }
122
123    pub fn into_vec(self) -> Vec<T> {
124        self.data
125    }
126
127    pub fn map<U>(self, mapper: impl FnMut(T) -> U) -> SmartList<U> {
128        SmartList {
129            data: self.data.into_iter().map(mapper).collect(),
130            total_count: self.total_count,
131            aggregations: self.aggregations,
132            summary: self.summary,
133        }
134    }
135
136    pub fn to_list<U>(&self, mapper: impl FnMut(&T) -> U) -> Vec<U> {
137        self.data.iter().map(mapper).collect()
138    }
139
140    pub fn to_set<U>(&self, mapper: impl FnMut(&T) -> U) -> std::collections::BTreeSet<U>
141    where
142        U: Ord,
143    {
144        self.data.iter().map(mapper).collect()
145    }
146
147    pub fn identity_map<K>(&self, mut key: impl FnMut(&T) -> K) -> BTreeMap<K, T>
148    where
149        K: Ord,
150        T: Clone,
151    {
152        self.data
153            .iter()
154            .map(|item| (key(item), item.clone()))
155            .collect()
156    }
157
158    pub fn group_by<K>(&self, mut key: impl FnMut(&T) -> K) -> BTreeMap<K, Vec<T>>
159    where
160        K: Ord,
161        T: Clone,
162    {
163        let mut groups = BTreeMap::new();
164        for item in &self.data {
165            groups
166                .entry(key(item))
167                .or_insert_with(Vec::new)
168                .push(item.clone());
169        }
170        groups
171    }
172
173    pub fn merge_by<K>(
174        &mut self,
175        incoming: impl IntoIterator<Item = T>,
176        mut key: impl FnMut(&T) -> K,
177    ) where
178        K: Eq + Hash,
179    {
180        let mut positions = self
181            .data
182            .iter()
183            .enumerate()
184            .map(|(index, item)| (key(item), index))
185            .collect::<std::collections::HashMap<_, _>>();
186        for item in incoming {
187            let item_key = key(&item);
188            if let Some(index) = positions.get(&item_key).copied() {
189                self.data[index] = item;
190            } else {
191                positions.insert(item_key, self.data.len());
192                self.data.push(item);
193            }
194        }
195    }
196
197    pub fn into_records(self) -> SmartList<Record>
198    where
199        T: Entity,
200    {
201        SmartList {
202            data: self.data.into_iter().map(Entity::into_record).collect(),
203            total_count: self.total_count,
204            aggregations: self.aggregations,
205            summary: self.summary,
206        }
207    }
208}
209
210impl<T> SmartList<T>
211where
212    T: IdentifiableEntity,
213{
214    pub fn ids(&self) -> Vec<Value> {
215        self.data.iter().map(IdentifiableEntity::id_value).collect()
216    }
217
218    pub fn map_by_id(&self) -> BTreeMap<String, T>
219    where
220        T: Clone,
221    {
222        self.data
223            .iter()
224            .map(|item| (id_key(&item.id_value()), item.clone()))
225            .collect()
226    }
227}
228
229impl<T> SmartList<T>
230where
231    T: VersionedEntity,
232{
233    pub fn versions(&self) -> Vec<i64> {
234        self.data.iter().map(VersionedEntity::version).collect()
235    }
236}
237
238impl<T> From<Vec<T>> for SmartList<T> {
239    fn from(data: Vec<T>) -> Self {
240        Self::new(data)
241    }
242}
243
244impl<T> Default for SmartList<T> {
245    fn default() -> Self {
246        Self::new(Vec::new())
247    }
248}
249
250impl<T> IntoIterator for SmartList<T> {
251    type Item = T;
252    type IntoIter = std::vec::IntoIter<T>;
253
254    fn into_iter(self) -> Self::IntoIter {
255        self.data.into_iter()
256    }
257}
258
259impl<'a, T> IntoIterator for &'a SmartList<T> {
260    type Item = &'a T;
261    type IntoIter = std::slice::Iter<'a, T>;
262
263    fn into_iter(self) -> Self::IntoIter {
264        self.data.iter()
265    }
266}
267
268impl<'a, T> IntoIterator for &'a mut SmartList<T> {
269    type Item = &'a mut T;
270    type IntoIter = std::slice::IterMut<'a, T>;
271
272    fn into_iter(self) -> Self::IntoIter {
273        self.data.iter_mut()
274    }
275}
276
277impl<T> FromIterator<T> for SmartList<T> {
278    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
279        Self::new(iter.into_iter().collect())
280    }
281}
282
283impl<T> Extend<T> for SmartList<T> {
284    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
285        self.data.extend(iter);
286    }
287}
288
289impl<T> Index<usize> for SmartList<T> {
290    type Output = T;
291
292    fn index(&self, index: usize) -> &Self::Output {
293        &self.data[index]
294    }
295}
296
297impl<T> IndexMut<usize> for SmartList<T> {
298    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
299        &mut self.data[index]
300    }
301}
302
303fn id_key(value: &Value) -> String {
304    match value {
305        Value::Null => "null".to_owned(),
306        Value::Bool(value) => format!("b:{value}"),
307        Value::I64(value) => format!("i:{value}"),
308        Value::U64(value) => format!("u:{value}"),
309        Value::F64(value) => format!("f:{value}"),
310        Value::Decimal(value) => format!("d:{value}"),
311        Value::Text(value) => format!("t:{value}"),
312        Value::Json(value) => format!("j:{value}"),
313        Value::Date(value) => format!("d:{value}"),
314        Value::Timestamp(value) => format!("ts:{}", value.to_rfc3339()),
315        Value::Object(_) => "object".to_owned(),
316        Value::List(_) => "list".to_owned(),
317    }
318}