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 #[must_use]
18 fn is_null(&self) -> bool;
19
20 #[must_use]
22 fn is_missing(&self) -> bool;
23
24 #[inline]
25 #[must_use]
27 fn is_absent(&self) -> bool {
28 self.is_null() || self.is_missing()
29 }
30
31 #[inline]
32 #[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}