1use crate::{
2 Bag, BagIntoIterator, BindingsName, Graph, List, ListIntoIterator, PairsIntoIter, PairsIter,
3 Tuple, Value,
4};
5use std::borrow::Cow;
6use std::collections::HashMap;
7use std::error::Error;
8
9use std::fmt::Debug;
10
11pub type DatumLowerError = Box<dyn Error>;
12pub type DatumLowerResult<T> = Result<T, DatumLowerError>;
13
14pub trait Datum<D>
15where
16 D: Datum<D>,
17{
18 #[must_use]
20 fn is_null(&self) -> bool;
21
22 #[must_use]
24 fn is_missing(&self) -> bool;
25
26 #[inline]
27 #[must_use]
29 fn is_absent(&self) -> bool {
30 self.is_null() || self.is_missing()
31 }
32
33 #[inline]
34 #[must_use]
36 fn is_present(&self) -> bool {
37 !self.is_absent()
38 }
39
40 #[must_use]
41 fn is_sequence(&self) -> bool;
42
43 #[must_use]
44 fn is_ordered(&self) -> bool;
45}
46
47pub trait DatumValue<D: Datum<D>>: Datum<D> + Clone + Debug {}
48
49pub trait DatumLower<D: DatumValue<D>>: Datum<D> + Debug {
50 fn into_lower(self) -> DatumLowerResult<D>;
51
52 fn into_lower_boxed(self: Box<Self>) -> DatumLowerResult<D>;
53 fn lower(&self) -> DatumLowerResult<Cow<'_, D>>;
54}
55
56pub trait DatumCategory<'a> {
57 fn category(&'a self) -> DatumCategoryRef<'a>;
58 fn into_category(self) -> DatumCategoryOwned;
59}
60
61#[derive(Debug)]
62pub enum DatumCategoryRef<'a> {
63 Null,
64 Missing,
65 Tuple(DatumTupleRef<'a>),
66 Sequence(DatumSeqRef<'a>),
67 Scalar(DatumValueRef<'a>),
68 Graph(DatumGraphRef<'a>),
69}
70
71#[derive(Debug)]
72pub enum DatumCategoryOwned {
73 Null,
74 Missing,
75 Tuple(DatumTupleOwned),
76 Sequence(DatumSeqOwned),
77 Scalar(DatumValueOwned),
78 Graph(DatumGraphOwned),
79}
80
81#[derive(Debug)]
82pub enum DatumTupleRef<'a> {
83 Empty,
85 Tuple(&'a Tuple),
87 Dynamic(&'a dyn RefTupleView<'a, Value>),
89 CoercedValue(usize, &'a Value),
91 SingleKey(Cow<'a, str>, &'a Value),
93 Bindings(&'a HashMap<Cow<'a, str>, &'a Value>),
95}
96
97#[derive(Debug)]
98pub enum DatumSeqRef<'a> {
99 List(&'a List),
100 Bag(&'a Bag),
101 Dynamic(&'a dyn RefSequenceView<'a, Value>),
102}
103
104#[derive(Debug)]
105pub enum DatumValueRef<'a> {
106 Value(&'a Value),
107 Dynamic(&'a dyn DatumLower<Value>),
108}
109
110#[derive(Debug)]
111pub enum DatumGraphRef<'a> {
112 Graph(&'a Graph),
113}
114
115#[derive(Debug)]
116pub enum DatumTupleOwned {
117 Tuple(Box<Tuple>),
118 Dynamic(Box<dyn OwnedTupleView<Value>>),
119}
120
121#[derive(Debug)]
122pub enum DatumSeqOwned {
123 List(Box<List>),
124 Bag(Box<Bag>),
125 Dynamic(Box<dyn OwnedSequenceView<Value>>),
126}
127
128#[derive(Debug)]
129pub enum DatumValueOwned {
130 Value(Value),
131}
132
133#[derive(Debug)]
134pub enum DatumGraphOwned {
135 Graph(Box<Graph>),
136}
137
138impl<'a> DatumCategory<'a> for Value {
139 fn category(&'a self) -> DatumCategoryRef<'a> {
140 match self {
141 Value::Null => DatumCategoryRef::Null,
142 Value::Missing => DatumCategoryRef::Missing,
143 Value::List(list) => DatumCategoryRef::Sequence(DatumSeqRef::List(list)),
144 Value::Bag(bag) => DatumCategoryRef::Sequence(DatumSeqRef::Bag(bag)),
145 Value::Tuple(tuple) => DatumCategoryRef::Tuple(DatumTupleRef::Tuple(tuple.as_ref())),
146 Value::Variant(doc) => doc.category(),
147 Value::Graph(graph) => DatumCategoryRef::Graph(DatumGraphRef::Graph(graph.as_ref())),
148 val => DatumCategoryRef::Scalar(DatumValueRef::Value(val)),
149 }
150 }
151
152 fn into_category(self) -> DatumCategoryOwned {
153 match self {
154 Value::Null => DatumCategoryOwned::Null,
155 Value::Missing => DatumCategoryOwned::Missing,
156 Value::List(list) => DatumCategoryOwned::Sequence(DatumSeqOwned::List(list)),
157 Value::Bag(bag) => DatumCategoryOwned::Sequence(DatumSeqOwned::Bag(bag)),
158 Value::Tuple(tuple) => DatumCategoryOwned::Tuple(DatumTupleOwned::Tuple(tuple)),
159 Value::Variant(doc) => doc.into_category(),
160 Value::Graph(graph) => DatumCategoryOwned::Graph(DatumGraphOwned::Graph(graph)),
161 val => DatumCategoryOwned::Scalar(DatumValueOwned::Value(val)),
162 }
163 }
164}
165
166pub struct RefFieldView<'a, DV: DatumValue<DV>> {
167 pub name: Option<&'a str>,
168 pub value: Cow<'a, DV>,
169}
170
171pub trait TupleDatum {
172 fn len(&self) -> usize;
173 fn is_empty(&self) -> bool {
174 self.len() == 0
175 }
176}
177
178pub trait RefTupleView<'a, DV: DatumValue<DV>>: TupleDatum + Debug {
179 fn get_val(&self, k: &BindingsName<'_>) -> Option<Cow<'a, DV>>;
180 fn tuple_fields_iter(&'a self) -> Box<dyn Iterator<Item = RefFieldView<'a, DV>> + 'a>;
181}
182
183pub struct OwnedFieldView<D: Datum<D>> {
184 pub name: String,
185 pub value: D,
186}
187
188pub trait OwnedTupleView<D: Datum<D>>: TupleDatum + Debug {
189 fn take_val(self, k: &BindingsName<'_>) -> Option<D>;
190 fn take_val_boxed(self: Box<Self>, k: &BindingsName<'_>) -> Option<D>;
191 fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = OwnedFieldView<D>>>;
192}
193
194pub trait SequenceDatum {
195 fn is_ordered(&self) -> bool;
196 fn len(&self) -> usize;
197 fn is_empty(&self) -> bool {
198 self.len() == 0
199 }
200}
201
202pub trait RefSequenceView<'a, DV: DatumValue<DV>>: SequenceDatum + Debug {
203 fn get_val(&self, k: i64) -> Option<Cow<'a, DV>>;
204 fn into_iter(self) -> Box<dyn Iterator<Item = Cow<'a, DV>> + 'a>;
205}
206
207pub trait OwnedSequenceView<D: Datum<D>>: SequenceDatum + Debug {
208 fn take_val(self, k: i64) -> Option<D>;
209 fn take_val_boxed(self: Box<Self>, k: i64) -> Option<D>;
210 fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = D>>;
211}
212
213impl TupleDatum for DatumTupleRef<'_> {
214 fn len(&self) -> usize {
215 match self {
216 DatumTupleRef::Tuple(tuple) => tuple.len(),
217 DatumTupleRef::Dynamic(dynamic) => dynamic.len(),
218 DatumTupleRef::Empty => 0,
219 DatumTupleRef::CoercedValue(_, _) => 1,
220 DatumTupleRef::SingleKey(_, _) => 1,
221 DatumTupleRef::Bindings(map) => map.len(),
222 }
223 }
224}
225
226impl<'a> RefTupleView<'a, Value> for DatumTupleRef<'a> {
227 fn get_val(&self, k: &BindingsName<'_>) -> Option<Cow<'a, Value>> {
228 match self {
229 DatumTupleRef::Tuple(tuple) => Tuple::get(tuple, k).map(Cow::Borrowed),
230 DatumTupleRef::Dynamic(dynamic) => dynamic.get_val(k),
231 DatumTupleRef::Empty => None,
232 DatumTupleRef::CoercedValue(idx, v) => {
233 if k.matcher().matches(&format!("_{idx}")) {
234 Some(Cow::Borrowed(v))
235 } else {
236 None
237 }
238 }
239 DatumTupleRef::SingleKey(key, v) => {
240 if k.matcher().matches(key.as_ref()) {
241 Some(Cow::Borrowed(v))
242 } else {
243 None
244 }
245 }
246 DatumTupleRef::Bindings(map) => {
247 let m = k.matcher();
248 map.iter()
249 .find_map(|(k, &v)| m.matches(k).then_some(Cow::Borrowed(v)))
250 }
251 }
252 }
253
254 fn tuple_fields_iter(&'a self) -> Box<dyn Iterator<Item = RefFieldView<'a, Value>> + 'a> {
255 Box::new(IntoIterator::into_iter(self))
256 }
257}
258
259impl<'a> IntoIterator for &'a DatumTupleRef<'a> {
260 type Item = RefFieldView<'a, Value>;
261 type IntoIter = DatumTupleRefIterator<'a>;
262
263 fn into_iter(self) -> Self::IntoIter {
264 match self {
265 DatumTupleRef::Tuple(t) => DatumTupleRefIterator::Tuple(t.pairs()),
266 DatumTupleRef::Empty => DatumTupleRefIterator::Empty,
267 DatumTupleRef::Dynamic(d) => DatumTupleRefIterator::Dynamic(d.tuple_fields_iter()),
268 DatumTupleRef::CoercedValue(idx, value) => {
269 DatumTupleRefIterator::CoercedValue(Some((*idx, value)))
270 }
271 DatumTupleRef::SingleKey(key, value) => {
272 DatumTupleRefIterator::SingleKey(Some((key.as_ref(), value)))
273 }
274 DatumTupleRef::Bindings(m) => {
275 DatumTupleRefIterator::Dynamic(Box::new(m.iter().map(|(k, &v)| RefFieldView {
276 name: Some(k.as_ref()),
277 value: Cow::Borrowed(v),
278 })))
279 }
280 }
281 }
282}
283
284pub enum DatumTupleRefIterator<'a> {
285 Empty,
286 Tuple(PairsIter<'a>),
287 Dynamic(Box<dyn Iterator<Item = RefFieldView<'a, Value>> + 'a>),
288 CoercedValue(Option<(usize, &'a Value)>),
289 SingleKey(Option<(&'a str, &'a Value)>),
290}
291
292impl<'a> Iterator for DatumTupleRefIterator<'a> {
293 type Item = RefFieldView<'a, Value>;
294
295 fn next(&mut self) -> Option<Self::Item> {
296 match self {
297 DatumTupleRefIterator::Tuple(t) => t.next().map(|(name, value)| RefFieldView {
298 name: Some(name),
299 value: Cow::Borrowed(value),
300 }),
301 DatumTupleRefIterator::Empty => None,
302 DatumTupleRefIterator::CoercedValue(payload) => {
303 payload.take().map(|(_, value)| RefFieldView {
304 name: None,
305 value: Cow::Borrowed(value),
306 })
307 }
308 DatumTupleRefIterator::Dynamic(d) => d.next(),
309 DatumTupleRefIterator::SingleKey(payload) => {
310 payload.take().map(|(key, value)| RefFieldView {
311 name: Some(key),
312 value: Cow::Borrowed(value),
313 })
314 }
315 }
316 }
317}
318
319impl TupleDatum for DatumTupleOwned {
320 fn len(&self) -> usize {
321 match self {
322 DatumTupleOwned::Tuple(tuple) => tuple.len(),
323 DatumTupleOwned::Dynamic(dynamic) => dynamic.len(),
324 }
325 }
326}
327
328impl OwnedTupleView<Value> for DatumTupleOwned {
329 fn take_val(self, k: &BindingsName<'_>) -> Option<Value> {
330 match self {
331 DatumTupleOwned::Tuple(tuple) => Tuple::take_val(*tuple, k),
332 DatumTupleOwned::Dynamic(dynamic) => dynamic.take_val_boxed(k),
333 }
334 }
335
336 fn take_val_boxed(self: Box<Self>, k: &BindingsName<'_>) -> Option<Value> {
337 (*self).take_val(k)
338 }
339
340 fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = OwnedFieldView<Value>>> {
341 Box::new((*self).into_iter())
342 }
343}
344
345impl SequenceDatum for DatumSeqRef<'_> {
346 fn is_ordered(&self) -> bool {
347 match self {
348 DatumSeqRef::List(_) => true,
349 DatumSeqRef::Bag(_) => false,
350 DatumSeqRef::Dynamic(boxed) => boxed.is_ordered(),
351 }
352 }
353
354 fn len(&self) -> usize {
355 match self {
356 DatumSeqRef::List(l) => l.len(),
357 DatumSeqRef::Bag(b) => b.len(),
358 DatumSeqRef::Dynamic(boxed) => boxed.len(),
359 }
360 }
361}
362
363impl<'a> RefSequenceView<'a, Value> for DatumSeqRef<'a> {
364 fn get_val(&self, k: i64) -> Option<Cow<'a, Value>> {
365 match self {
366 DatumSeqRef::List(l) => List::get(l, k).map(Cow::Borrowed),
367 DatumSeqRef::Bag(_) => None,
368 DatumSeqRef::Dynamic(boxed) => boxed.get_val(k),
369 }
370 }
371
372 fn into_iter(self) -> Box<dyn Iterator<Item = Cow<'a, Value>> + 'a> {
373 match self {
374 DatumSeqRef::List(l) => Box::new(l.iter().map(Cow::Borrowed)),
375 DatumSeqRef::Bag(b) => Box::new(b.iter().map(Cow::Borrowed)),
376 DatumSeqRef::Dynamic(_boxed) => todo!("&dyn RefSequenceView into_iter"),
377 }
378 }
379}
380
381impl SequenceDatum for DatumSeqOwned {
382 fn is_ordered(&self) -> bool {
383 match self {
384 DatumSeqOwned::List(_) => true,
385 DatumSeqOwned::Bag(_) => false,
386 DatumSeqOwned::Dynamic(boxed) => boxed.is_ordered(),
387 }
388 }
389
390 fn len(&self) -> usize {
391 match self {
392 DatumSeqOwned::List(l) => l.len(),
393 DatumSeqOwned::Bag(b) => b.len(),
394 DatumSeqOwned::Dynamic(boxed) => boxed.len(),
395 }
396 }
397}
398
399impl OwnedSequenceView<Value> for DatumSeqOwned {
400 fn take_val(self, k: i64) -> Option<Value> {
401 match self {
402 DatumSeqOwned::List(l) => l.take_val(k),
403 DatumSeqOwned::Bag(_) => None,
404 DatumSeqOwned::Dynamic(boxed) => boxed.take_val_boxed(k),
405 }
406 }
407
408 fn take_val_boxed(self: Box<Self>, k: i64) -> Option<Value> {
409 self.take_val(k)
410 }
411
412 fn into_iter_boxed(self: Box<Self>) -> Box<dyn Iterator<Item = Value>> {
413 Box::new((*self).into_iter())
414 }
415}
416
417impl IntoIterator for DatumTupleOwned {
418 type Item = OwnedFieldView<Value>;
419 type IntoIter = DatumTupleOwnedIterator;
420
421 fn into_iter(self) -> Self::IntoIter {
422 match self {
423 DatumTupleOwned::Tuple(t) => DatumTupleOwnedIterator::Tuple(t.into_pairs()),
424 DatumTupleOwned::Dynamic(d) => DatumTupleOwnedIterator::Dynamic(d.into_iter_boxed()),
425 }
426 }
427}
428
429pub enum DatumTupleOwnedIterator {
430 Tuple(PairsIntoIter),
431 Dynamic(Box<dyn Iterator<Item = OwnedFieldView<Value>>>),
432}
433
434impl Iterator for DatumTupleOwnedIterator {
435 type Item = OwnedFieldView<Value>;
436
437 fn next(&mut self) -> Option<Self::Item> {
438 match self {
439 DatumTupleOwnedIterator::Tuple(t) => {
440 t.next().map(|(name, value)| OwnedFieldView { name, value })
441 }
442 DatumTupleOwnedIterator::Dynamic(d) => d.next(),
443 }
444 }
445}
446
447impl IntoIterator for DatumSeqOwned {
448 type Item = Value;
449 type IntoIter = DatumSeqOwnedIterator;
450
451 fn into_iter(self) -> Self::IntoIter {
452 match self {
453 DatumSeqOwned::List(l) => DatumSeqOwnedIterator::List(l.into_iter()),
454 DatumSeqOwned::Bag(b) => DatumSeqOwnedIterator::Bag(b.into_iter()),
455 DatumSeqOwned::Dynamic(d) => DatumSeqOwnedIterator::Dynamic(d.into_iter_boxed()),
456 }
457 }
458}
459
460pub enum DatumSeqOwnedIterator {
461 List(ListIntoIterator),
462 Bag(BagIntoIterator),
463 Dynamic(Box<dyn Iterator<Item = Value>>),
464}
465
466impl Iterator for DatumSeqOwnedIterator {
467 type Item = Value;
468
469 fn next(&mut self) -> Option<Self::Item> {
470 match self {
471 DatumSeqOwnedIterator::List(l) => l.next(),
472 DatumSeqOwnedIterator::Bag(b) => b.next(),
473 DatumSeqOwnedIterator::Dynamic(d) => d.next(),
474 }
475 }
476}
477
478impl Datum<Value> for DatumValueRef<'_> {
479 #[inline]
480 fn is_null(&self) -> bool {
481 match self {
482 DatumValueRef::Value(v) => v.is_null(),
483 DatumValueRef::Dynamic(d) => d.is_null(),
484 }
485 }
486
487 #[inline]
488 fn is_missing(&self) -> bool {
489 match self {
490 DatumValueRef::Value(v) => v.is_missing(),
491 DatumValueRef::Dynamic(d) => d.is_missing(),
492 }
493 }
494
495 #[inline]
496 fn is_sequence(&self) -> bool {
497 match self {
498 DatumValueRef::Value(v) => v.is_sequence(),
499 DatumValueRef::Dynamic(d) => d.is_sequence(),
500 }
501 }
502
503 #[inline]
504 fn is_ordered(&self) -> bool {
505 match self {
506 DatumValueRef::Value(v) => v.is_ordered(),
507 DatumValueRef::Dynamic(d) => d.is_ordered(),
508 }
509 }
510}
511
512impl Datum<Value> for DatumValueOwned {
513 #[inline]
514 fn is_null(&self) -> bool {
515 match self {
516 DatumValueOwned::Value(v) => v.is_null(),
517 }
518 }
519
520 #[inline]
521 fn is_missing(&self) -> bool {
522 match self {
523 DatumValueOwned::Value(v) => v.is_missing(),
524 }
525 }
526
527 #[inline]
528 fn is_sequence(&self) -> bool {
529 match self {
530 DatumValueOwned::Value(v) => v.is_sequence(),
531 }
532 }
533
534 #[inline]
535 fn is_ordered(&self) -> bool {
536 match self {
537 DatumValueOwned::Value(v) => v.is_ordered(),
538 }
539 }
540}
541
542impl DatumLower<Value> for DatumValueOwned {
543 #[inline]
544 fn into_lower(self) -> DatumLowerResult<Value> {
545 match self {
546 DatumValueOwned::Value(v) => v.into_lower(),
547 }
548 }
549
550 #[inline]
551 fn into_lower_boxed(self: Box<Self>) -> DatumLowerResult<Value> {
552 match *self {
553 DatumValueOwned::Value(v) => v.into_lower(),
554 }
555 }
556
557 #[inline]
558 fn lower(&self) -> DatumLowerResult<Cow<'_, Value>> {
559 match self {
560 DatumValueOwned::Value(v) => v.lower(),
561 }
562 }
563}