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