partiql_value/
datum.rs

1use crate::{
2    Bag, BagIntoIterator, BindingsName, Graph, List, ListIntoIterator, PairsIntoIter, Tuple, Value,
3};
4use std::borrow::Cow;
5use std::error::Error;
6
7use std::fmt::Debug;
8
9pub type DatumLowerError = Box<dyn Error>;
10pub type DatumLowerResult<T> = Result<T, DatumLowerError>;
11
12pub trait Datum<D>
13where
14    D: Datum<D>,
15{
16    /// Returns true if and only if Value is to be interpreted as `NULL`
17    #[must_use]
18    fn is_null(&self) -> bool;
19
20    /// Returns true if and only if Value is to be interpreted as `MISSING`
21    #[must_use]
22    fn is_missing(&self) -> bool;
23
24    #[inline]
25    /// Returns true if and only if Value is null or missing
26    #[must_use]
27    fn is_absent(&self) -> bool {
28        self.is_null() || self.is_missing()
29    }
30
31    #[inline]
32    /// Returns true if Value is neither null nor missing
33    #[must_use]
34    fn is_present(&self) -> bool {
35        !self.is_absent()
36    }
37
38    #[must_use]
39    fn is_sequence(&self) -> bool;
40
41    #[must_use]
42    fn is_ordered(&self) -> bool;
43}
44
45pub trait DatumValue<D: Datum<D>>: Datum<D> + Clone + Debug {}
46
47pub trait DatumLower<D: DatumValue<D>>: Datum<D> + Debug {
48    fn into_lower(self) -> DatumLowerResult<D>;
49
50    fn into_lower_boxed(self: Box<Self>) -> DatumLowerResult<D>;
51    fn lower(&self) -> DatumLowerResult<Cow<'_, D>>;
52}
53
54pub trait DatumCategory<'a> {
55    fn category(&'a self) -> DatumCategoryRef<'a>;
56    fn into_category(self) -> DatumCategoryOwned;
57}
58
59#[derive(Debug)]
60pub enum DatumCategoryRef<'a> {
61    Null,
62    Missing,
63    Tuple(DatumTupleRef<'a>),
64    Sequence(DatumSeqRef<'a>),
65    Scalar(DatumValueRef<'a>),
66    Graph(DatumGraphRef<'a>),
67}
68
69#[derive(Debug)]
70pub enum DatumCategoryOwned {
71    Null,
72    Missing,
73    Tuple(DatumTupleOwned),
74    Sequence(DatumSeqOwned),
75    Scalar(DatumValueOwned),
76    Graph(DatumGraphOwned),
77}
78
79#[derive(Debug)]
80pub enum DatumTupleRef<'a> {
81    Tuple(&'a Tuple),
82    Dynamic(&'a dyn RefTupleView<'a, Value>),
83}
84
85#[derive(Debug)]
86pub enum DatumSeqRef<'a> {
87    List(&'a List),
88    Bag(&'a Bag),
89    Dynamic(&'a dyn RefSequenceView<'a, Value>),
90}
91
92#[derive(Debug)]
93pub enum DatumValueRef<'a> {
94    Value(&'a Value),
95    Dynamic(&'a dyn DatumLower<Value>),
96}
97
98#[derive(Debug)]
99pub enum DatumGraphRef<'a> {
100    Graph(&'a Graph),
101}
102
103#[derive(Debug)]
104pub enum DatumTupleOwned {
105    Tuple(Box<Tuple>),
106    Dynamic(Box<dyn OwnedTupleView<Value>>),
107}
108
109#[derive(Debug)]
110pub enum DatumSeqOwned {
111    List(Box<List>),
112    Bag(Box<Bag>),
113    Dynamic(Box<dyn OwnedSequenceView<Value>>),
114}
115
116#[derive(Debug)]
117pub enum DatumValueOwned {
118    Value(Value),
119}
120
121#[derive(Debug)]
122pub enum DatumGraphOwned {
123    Graph(Box<Graph>),
124}
125
126impl<'a> DatumCategory<'a> for Value {
127    fn category(&'a self) -> DatumCategoryRef<'a> {
128        match self {
129            Value::Null => DatumCategoryRef::Null,
130            Value::Missing => DatumCategoryRef::Missing,
131            Value::List(list) => DatumCategoryRef::Sequence(DatumSeqRef::List(list)),
132            Value::Bag(bag) => DatumCategoryRef::Sequence(DatumSeqRef::Bag(bag)),
133            Value::Tuple(tuple) => DatumCategoryRef::Tuple(DatumTupleRef::Tuple(tuple.as_ref())),
134            Value::Variant(doc) => doc.category(),
135            Value::Graph(graph) => DatumCategoryRef::Graph(DatumGraphRef::Graph(graph.as_ref())),
136            val => DatumCategoryRef::Scalar(DatumValueRef::Value(val)),
137        }
138    }
139
140    fn into_category(self) -> DatumCategoryOwned {
141        match self {
142            Value::Null => DatumCategoryOwned::Null,
143            Value::Missing => DatumCategoryOwned::Missing,
144            Value::List(list) => DatumCategoryOwned::Sequence(DatumSeqOwned::List(list)),
145            Value::Bag(bag) => DatumCategoryOwned::Sequence(DatumSeqOwned::Bag(bag)),
146            Value::Tuple(tuple) => DatumCategoryOwned::Tuple(DatumTupleOwned::Tuple(tuple)),
147            Value::Variant(doc) => doc.into_category(),
148            Value::Graph(graph) => DatumCategoryOwned::Graph(DatumGraphOwned::Graph(graph)),
149            val => DatumCategoryOwned::Scalar(DatumValueOwned::Value(val)),
150        }
151    }
152}
153
154pub trait TupleDatum {
155    fn len(&self) -> usize;
156    fn is_empty(&self) -> bool {
157        self.len() == 0
158    }
159}
160
161pub trait RefTupleView<'a, DV: DatumValue<DV>>: TupleDatum + Debug {
162    fn get_val(&self, k: &BindingsName<'_>) -> Option<Cow<'a, DV>>;
163}
164
165pub struct OwnedFieldView<D: Datum<D>> {
166    pub name: String,
167    pub value: D,
168}
169
170pub trait OwnedTupleView<D: Datum<D>>: TupleDatum + Debug {
171    fn take_val(self, k: &BindingsName<'_>) -> Option<D>;
172    fn take_val_boxed(self: Box<Self>, k: &BindingsName<'_>) -> Option<D>;
173    fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = OwnedFieldView<D>>>;
174}
175
176pub trait SequenceDatum {
177    fn is_ordered(&self) -> bool;
178    fn len(&self) -> usize;
179    fn is_empty(&self) -> bool {
180        self.len() == 0
181    }
182}
183
184pub trait RefSequenceView<'a, DV: DatumValue<DV>>: SequenceDatum + Debug {
185    fn get_val(&self, k: i64) -> Option<Cow<'a, DV>>;
186    fn into_iter(self) -> Box<dyn Iterator<Item = Cow<'a, DV>> + 'a>;
187}
188
189pub trait OwnedSequenceView<D: Datum<D>>: SequenceDatum + Debug {
190    fn take_val(self, k: i64) -> Option<D>;
191    fn take_val_boxed(self: Box<Self>, k: i64) -> Option<D>;
192    fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = D>>;
193}
194
195impl TupleDatum for DatumTupleRef<'_> {
196    fn len(&self) -> usize {
197        match self {
198            DatumTupleRef::Tuple(tuple) => tuple.len(),
199            DatumTupleRef::Dynamic(dynamic) => dynamic.len(),
200        }
201    }
202}
203
204impl<'a> RefTupleView<'a, Value> for DatumTupleRef<'a> {
205    fn get_val(&self, k: &BindingsName<'_>) -> Option<Cow<'a, Value>> {
206        match self {
207            DatumTupleRef::Tuple(tuple) => Tuple::get(tuple, k).map(Cow::Borrowed),
208            DatumTupleRef::Dynamic(dynamic) => dynamic.get_val(k),
209        }
210    }
211}
212
213impl TupleDatum for DatumTupleOwned {
214    fn len(&self) -> usize {
215        match self {
216            DatumTupleOwned::Tuple(tuple) => tuple.len(),
217            DatumTupleOwned::Dynamic(dynamic) => dynamic.len(),
218        }
219    }
220}
221
222impl OwnedTupleView<Value> for DatumTupleOwned {
223    fn take_val(self, k: &BindingsName<'_>) -> Option<Value> {
224        match self {
225            DatumTupleOwned::Tuple(tuple) => Tuple::take_val(*tuple, k),
226            DatumTupleOwned::Dynamic(dynamic) => dynamic.take_val_boxed(k),
227        }
228    }
229
230    fn take_val_boxed(self: Box<Self>, k: &BindingsName<'_>) -> Option<Value> {
231        (*self).take_val(k)
232    }
233
234    fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = OwnedFieldView<Value>>> {
235        Box::new((*self).into_iter())
236    }
237}
238
239impl SequenceDatum for DatumSeqRef<'_> {
240    fn is_ordered(&self) -> bool {
241        match self {
242            DatumSeqRef::List(_) => true,
243            DatumSeqRef::Bag(_) => false,
244            DatumSeqRef::Dynamic(boxed) => boxed.is_ordered(),
245        }
246    }
247
248    fn len(&self) -> usize {
249        match self {
250            DatumSeqRef::List(l) => l.len(),
251            DatumSeqRef::Bag(b) => b.len(),
252            DatumSeqRef::Dynamic(boxed) => boxed.len(),
253        }
254    }
255}
256
257impl<'a> RefSequenceView<'a, Value> for DatumSeqRef<'a> {
258    fn get_val(&self, k: i64) -> Option<Cow<'a, Value>> {
259        match self {
260            DatumSeqRef::List(l) => List::get(l, k).map(Cow::Borrowed),
261            DatumSeqRef::Bag(_) => None,
262            DatumSeqRef::Dynamic(boxed) => boxed.get_val(k),
263        }
264    }
265
266    fn into_iter(self) -> Box<dyn Iterator<Item = Cow<'a, Value>> + 'a> {
267        match self {
268            DatumSeqRef::List(l) => Box::new(l.iter().map(Cow::Borrowed)),
269            DatumSeqRef::Bag(b) => Box::new(b.iter().map(Cow::Borrowed)),
270            DatumSeqRef::Dynamic(_boxed) => todo!("&dyn RefSequenceView into_iter"),
271        }
272    }
273}
274
275impl SequenceDatum for DatumSeqOwned {
276    fn is_ordered(&self) -> bool {
277        match self {
278            DatumSeqOwned::List(_) => true,
279            DatumSeqOwned::Bag(_) => false,
280            DatumSeqOwned::Dynamic(boxed) => boxed.is_ordered(),
281        }
282    }
283
284    fn len(&self) -> usize {
285        match self {
286            DatumSeqOwned::List(l) => l.len(),
287            DatumSeqOwned::Bag(b) => b.len(),
288            DatumSeqOwned::Dynamic(boxed) => boxed.len(),
289        }
290    }
291}
292
293impl OwnedSequenceView<Value> for DatumSeqOwned {
294    fn take_val(self, k: i64) -> Option<Value> {
295        match self {
296            DatumSeqOwned::List(l) => l.take_val(k),
297            DatumSeqOwned::Bag(_) => None,
298            DatumSeqOwned::Dynamic(boxed) => boxed.take_val_boxed(k),
299        }
300    }
301
302    fn take_val_boxed(self: Box<Self>, k: i64) -> Option<Value> {
303        self.take_val(k)
304    }
305
306    fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = Value>> {
307        Box::new((*self).into_iter())
308    }
309}
310
311impl IntoIterator for DatumTupleOwned {
312    type Item = OwnedFieldView<Value>;
313    type IntoIter = DatumTupleOwnedIterator;
314
315    fn into_iter(self) -> Self::IntoIter {
316        match self {
317            DatumTupleOwned::Tuple(t) => DatumTupleOwnedIterator::Tuple(t.into_pairs()),
318            DatumTupleOwned::Dynamic(d) => DatumTupleOwnedIterator::Dynamic(d.into_iter_boxed()),
319        }
320    }
321}
322
323pub enum DatumTupleOwnedIterator {
324    Tuple(PairsIntoIter),
325    Dynamic(Box<dyn Iterator<Item = OwnedFieldView<Value>>>),
326}
327
328impl Iterator for DatumTupleOwnedIterator {
329    type Item = OwnedFieldView<Value>;
330
331    fn next(&mut self) -> Option<Self::Item> {
332        match self {
333            DatumTupleOwnedIterator::Tuple(t) => {
334                t.next().map(|(name, value)| OwnedFieldView { name, value })
335            }
336            DatumTupleOwnedIterator::Dynamic(d) => d.next(),
337        }
338    }
339}
340
341impl IntoIterator for DatumSeqOwned {
342    type Item = Value;
343    type IntoIter = DatumSeqOwnedIterator;
344
345    fn into_iter(self) -> Self::IntoIter {
346        match self {
347            DatumSeqOwned::List(l) => DatumSeqOwnedIterator::List(l.into_iter()),
348            DatumSeqOwned::Bag(b) => DatumSeqOwnedIterator::Bag(b.into_iter()),
349            DatumSeqOwned::Dynamic(d) => DatumSeqOwnedIterator::Dynamic(d.into_iter_boxed()),
350        }
351    }
352}
353
354pub enum DatumSeqOwnedIterator {
355    List(ListIntoIterator),
356    Bag(BagIntoIterator),
357    Dynamic(Box<dyn Iterator<Item = Value>>),
358}
359
360impl Iterator for DatumSeqOwnedIterator {
361    type Item = Value;
362
363    fn next(&mut self) -> Option<Self::Item> {
364        match self {
365            DatumSeqOwnedIterator::List(l) => l.next(),
366            DatumSeqOwnedIterator::Bag(b) => b.next(),
367            DatumSeqOwnedIterator::Dynamic(d) => d.next(),
368        }
369    }
370}
371
372impl Datum<Value> for DatumValueRef<'_> {
373    #[inline]
374    fn is_null(&self) -> bool {
375        match self {
376            DatumValueRef::Value(v) => v.is_null(),
377            DatumValueRef::Dynamic(d) => d.is_null(),
378        }
379    }
380
381    #[inline]
382    fn is_missing(&self) -> bool {
383        match self {
384            DatumValueRef::Value(v) => v.is_missing(),
385            DatumValueRef::Dynamic(d) => d.is_missing(),
386        }
387    }
388
389    #[inline]
390    fn is_sequence(&self) -> bool {
391        match self {
392            DatumValueRef::Value(v) => v.is_sequence(),
393            DatumValueRef::Dynamic(d) => d.is_sequence(),
394        }
395    }
396
397    #[inline]
398    fn is_ordered(&self) -> bool {
399        match self {
400            DatumValueRef::Value(v) => v.is_ordered(),
401            DatumValueRef::Dynamic(d) => d.is_ordered(),
402        }
403    }
404}
405
406impl Datum<Value> for DatumValueOwned {
407    #[inline]
408    fn is_null(&self) -> bool {
409        match self {
410            DatumValueOwned::Value(v) => v.is_null(),
411        }
412    }
413
414    #[inline]
415    fn is_missing(&self) -> bool {
416        match self {
417            DatumValueOwned::Value(v) => v.is_missing(),
418        }
419    }
420
421    #[inline]
422    fn is_sequence(&self) -> bool {
423        match self {
424            DatumValueOwned::Value(v) => v.is_sequence(),
425        }
426    }
427
428    #[inline]
429    fn is_ordered(&self) -> bool {
430        match self {
431            DatumValueOwned::Value(v) => v.is_ordered(),
432        }
433    }
434}
435
436impl DatumLower<Value> for DatumValueOwned {
437    #[inline]
438    fn into_lower(self) -> DatumLowerResult<Value> {
439        match self {
440            DatumValueOwned::Value(v) => v.into_lower(),
441        }
442    }
443
444    #[inline]
445    fn into_lower_boxed(self: Box<Self>) -> DatumLowerResult<Value> {
446        match *self {
447            DatumValueOwned::Value(v) => v.into_lower(),
448        }
449    }
450
451    #[inline]
452    fn lower(&self) -> DatumLowerResult<Cow<'_, Value>> {
453        match self {
454            DatumValueOwned::Value(v) => v.lower(),
455        }
456    }
457}