1use crate::Field;
30use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
31use std::sync::Arc;
32
33pub trait FieldSelector {
41 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize>;
43
44 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync>;
46}
47
48pub trait DataSelector {
50 fn resolve_indices(&self, count: usize) -> Vec<usize>;
52
53 fn is_contiguous(&self) -> bool {
57 false }
59
60 #[cfg(feature = "ndarray")]
66 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
67 let indices = self.resolve_indices(usize::MAX);
70 assert_eq!(
71 indices.len(), 1,
72 "axis selection: index arrays take a single index or a contiguous range; gather with r() instead"
73 );
74 assert!(
75 indices[0] < dim_size,
76 "axis selection: index {} out of bounds (size {})", indices[0], dim_size
77 );
78 (indices[0], indices[0] + 1, true)
79 }
80}
81
82pub trait ColumnSelection {
93 type View;
95 type ColumnView;
97 type ColumnOwned;
99
100 fn c<S: FieldSelector>(&self, selection: S) -> Self::View;
112
113 fn col(&self, name: &str) -> Self::View {
126 self.c(name)
127 }
128
129 fn get(&self, field: &str) -> Option<Self::ColumnOwned>;
131
132 fn col_ix(&self, idx: usize) -> Option<Self::ColumnView>;
134
135 fn col_vec(&self) -> Vec<Self::ColumnView>;
137
138 fn get_cols(&self) -> Vec<Arc<Field>>;
140}
141
142pub trait RowSelection {
144 type View;
146
147 fn r<S: DataSelector>(&self, selection: S) -> Self::View;
158
159 fn row(&self, idx: usize) -> Self::View {
171 self.r(idx)
172 }
173
174 fn get_row_count(&self) -> usize;
176}
177
178#[cfg(feature = "ndarray")]
192pub trait AxisSelection {
193 type View;
195
196 fn s(&self, selection: &[&dyn DataSelector]) -> Self::View;
211
212 fn select(&self, selection: &[&dyn DataSelector]) -> Self::View {
224 self.s(selection)
225 }
226
227 fn get_axis_count(&self) -> usize;
229}
230
231pub trait Selection2D: ColumnSelection + RowSelection {}
236
237impl<T> Selection2D for T where
239 T: ColumnSelection + RowSelection<View = <T as ColumnSelection>::View>
240{
241}
242
243impl FieldSelector for &str {
248 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
249 fields
250 .iter()
251 .position(|f| f.name == *self)
252 .into_iter()
253 .collect()
254 }
255 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
256 Box::new(vec![self.to_string()])
257 }
258}
259
260impl FieldSelector for &[&str] {
262 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
263 self.iter()
264 .filter_map(|name| fields.iter().position(|f| f.name == *name))
265 .collect()
266 }
267 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
268 Box::new(self.iter().map(|s| s.to_string()).collect::<Vec<String>>())
269 }
270}
271
272impl<const N: usize> FieldSelector for &[&str; N] {
274 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
275 self.iter()
276 .filter_map(|name| fields.iter().position(|f| f.name == *name))
277 .collect()
278 }
279 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
280 Box::new(self.iter().map(|s| s.to_string()).collect::<Vec<String>>())
281 }
282}
283
284impl FieldSelector for Vec<&str> {
286 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
287 self.iter()
288 .filter_map(|name| fields.iter().position(|f| f.name == *name))
289 .collect()
290 }
291 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
292 Box::new(self.iter().map(|s| s.to_string()).collect::<Vec<String>>())
293 }
294}
295
296impl FieldSelector for Vec<String> {
298 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
299 self.iter()
300 .filter_map(|name| fields.iter().position(|f| f.name.as_str() == name.as_str()))
301 .collect()
302 }
303 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
304 Box::new(self.clone())
305 }
306}
307
308impl FieldSelector for usize {
310 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
311 if *self < fields.len() {
312 vec![*self]
313 } else {
314 Vec::new()
315 }
316 }
317 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
318 Box::new(vec![*self])
319 }
320}
321
322impl FieldSelector for &[usize] {
324 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
325 self.iter()
326 .copied()
327 .filter(|&idx| idx < fields.len())
328 .collect()
329 }
330 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
331 Box::new(self.to_vec())
332 }
333}
334
335impl<const N: usize> FieldSelector for &[usize; N] {
337 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
338 self.iter()
339 .copied()
340 .filter(|&idx| idx < fields.len())
341 .collect()
342 }
343 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
344 Box::new(self.to_vec())
345 }
346}
347
348impl FieldSelector for Vec<usize> {
350 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
351 self.iter()
352 .copied()
353 .filter(|&idx| idx < fields.len())
354 .collect()
355 }
356 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
357 Box::new(self.clone())
358 }
359}
360
361impl FieldSelector for Range<usize> {
363 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
364 let end = self.end.min(fields.len());
365 (self.start..end).collect()
366 }
367 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
368 Box::new(self.clone())
369 }
370}
371
372impl FieldSelector for RangeFrom<usize> {
374 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
375 (self.start..fields.len()).collect()
376 }
377 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
378 Box::new(self.clone())
379 }
380}
381
382impl FieldSelector for RangeTo<usize> {
384 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
385 let end = self.end.min(fields.len());
386 (0..end).collect()
387 }
388 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
389 Box::new(self.clone())
390 }
391}
392
393impl FieldSelector for RangeFull {
395 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
396 (0..fields.len()).collect()
397 }
398 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
399 Box::new(..)
400 }
401}
402
403impl FieldSelector for RangeInclusive<usize> {
405 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
406 let start = *self.start();
407 let end = (*self.end() + 1).min(fields.len());
408 (start..end).collect()
409 }
410 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
411 Box::new(self.clone())
412 }
413}
414
415impl FieldSelector for Box<dyn FieldSelector + Send + Sync> {
417 fn resolve_fields(&self, fields: &[Arc<Field>]) -> Vec<usize> {
418 (**self).resolve_fields(fields)
419 }
420 fn to_owned(&self) -> Box<dyn FieldSelector + Send + Sync> {
421 (**self).to_owned()
422 }
423}
424
425impl DataSelector for usize {
430 fn resolve_indices(&self, count: usize) -> Vec<usize> {
431 if *self < count {
432 vec![*self]
433 } else {
434 Vec::new()
435 }
436 }
437
438 fn is_contiguous(&self) -> bool {
440 true
441 }
442
443 #[cfg(feature = "ndarray")]
444 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
445 assert!(
446 *self < dim_size,
447 "axis selection: index {} out of bounds (size {})", self, dim_size
448 );
449 (*self, *self + 1, true)
450 }
451}
452
453impl DataSelector for i32 {
456 fn resolve_indices(&self, count: usize) -> Vec<usize> {
457 if *self >= 0 && (*self as usize) < count {
458 vec![*self as usize]
459 } else {
460 Vec::new()
461 }
462 }
463
464 fn is_contiguous(&self) -> bool {
466 true
467 }
468
469 #[cfg(feature = "ndarray")]
470 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
471 assert!(
472 *self >= 0 && (*self as usize) < dim_size,
473 "axis selection: index {} out of bounds (size {})", self, dim_size
474 );
475 (*self as usize, *self as usize + 1, true)
476 }
477}
478
479impl DataSelector for &[usize] {
481 fn resolve_indices(&self, count: usize) -> Vec<usize> {
482 self.iter().copied().filter(|&idx| idx < count).collect()
483 }
484}
485
486impl<const N: usize> DataSelector for &[usize; N] {
488 fn resolve_indices(&self, count: usize) -> Vec<usize> {
489 self.iter().copied().filter(|&idx| idx < count).collect()
490 }
491}
492
493impl DataSelector for Vec<usize> {
495 fn resolve_indices(&self, count: usize) -> Vec<usize> {
496 self.iter().copied().filter(|&idx| idx < count).collect()
497 }
498}
499
500impl DataSelector for Range<usize> {
502 fn resolve_indices(&self, count: usize) -> Vec<usize> {
503 let end = self.end.min(count);
504 (self.start..end).collect()
505 }
506
507 fn is_contiguous(&self) -> bool {
508 true
509 }
510
511 #[cfg(feature = "ndarray")]
512 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
513 assert!(
514 self.start <= self.end && self.end <= dim_size,
515 "axis selection: range {}..{} out of bounds (size {})",
516 self.start, self.end, dim_size
517 );
518 (self.start, self.end, false)
519 }
520}
521
522impl DataSelector for Range<i32> {
525 fn resolve_indices(&self, count: usize) -> Vec<usize> {
526 let start = self.start.max(0) as usize;
527 let end = (self.end.max(0) as usize).min(count);
528 (start..end).collect()
529 }
530
531 fn is_contiguous(&self) -> bool {
532 true
533 }
534
535 #[cfg(feature = "ndarray")]
536 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
537 assert!(
538 self.start >= 0 && self.end >= self.start && (self.end as usize) <= dim_size,
539 "axis selection: range {}..{} out of bounds (size {})",
540 self.start, self.end, dim_size
541 );
542 (self.start as usize, self.end as usize, false)
543 }
544}
545
546impl DataSelector for RangeFrom<usize> {
548 fn resolve_indices(&self, count: usize) -> Vec<usize> {
549 (self.start..count).collect()
550 }
551
552 fn is_contiguous(&self) -> bool {
553 true
554 }
555
556 #[cfg(feature = "ndarray")]
557 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
558 assert!(
559 self.start <= dim_size,
560 "axis selection: range {}.. out of bounds (size {})", self.start, dim_size
561 );
562 (self.start, dim_size, false)
563 }
564}
565
566impl DataSelector for RangeFrom<i32> {
568 fn resolve_indices(&self, count: usize) -> Vec<usize> {
569 let start = self.start.max(0) as usize;
570 (start..count).collect()
571 }
572
573 fn is_contiguous(&self) -> bool {
574 true
575 }
576
577 #[cfg(feature = "ndarray")]
578 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
579 assert!(
580 self.start >= 0 && (self.start as usize) <= dim_size,
581 "axis selection: range {}.. out of bounds (size {})", self.start, dim_size
582 );
583 (self.start as usize, dim_size, false)
584 }
585}
586
587impl DataSelector for RangeTo<usize> {
589 fn resolve_indices(&self, count: usize) -> Vec<usize> {
590 let end = self.end.min(count);
591 (0..end).collect()
592 }
593
594 fn is_contiguous(&self) -> bool {
595 true
596 }
597
598 #[cfg(feature = "ndarray")]
599 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
600 assert!(
601 self.end <= dim_size,
602 "axis selection: range ..{} out of bounds (size {})", self.end, dim_size
603 );
604 (0, self.end, false)
605 }
606}
607
608impl DataSelector for RangeTo<i32> {
611 fn resolve_indices(&self, count: usize) -> Vec<usize> {
612 let end = (self.end.max(0) as usize).min(count);
613 (0..end).collect()
614 }
615
616 fn is_contiguous(&self) -> bool {
617 true
618 }
619
620 #[cfg(feature = "ndarray")]
621 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
622 assert!(
623 self.end >= 0 && (self.end as usize) <= dim_size,
624 "axis selection: range ..{} out of bounds (size {})", self.end, dim_size
625 );
626 (0, self.end as usize, false)
627 }
628}
629
630impl DataSelector for RangeFull {
632 fn resolve_indices(&self, count: usize) -> Vec<usize> {
633 (0..count).collect()
634 }
635
636 fn is_contiguous(&self) -> bool {
637 true
638 }
639
640 #[cfg(feature = "ndarray")]
641 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
642 (0, dim_size, false)
643 }
644}
645
646impl DataSelector for RangeInclusive<usize> {
648 fn resolve_indices(&self, count: usize) -> Vec<usize> {
649 let start = *self.start();
650 let end = (*self.end() + 1).min(count);
651 (start..end).collect()
652 }
653
654 fn is_contiguous(&self) -> bool {
655 true
656 }
657
658 #[cfg(feature = "ndarray")]
659 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
660 assert!(
661 self.start() <= self.end() && *self.end() < dim_size,
662 "axis selection: range {}..={} out of bounds (size {})",
663 self.start(), self.end(), dim_size
664 );
665 (*self.start(), *self.end() + 1, false)
666 }
667}
668
669impl DataSelector for RangeInclusive<i32> {
672 fn resolve_indices(&self, count: usize) -> Vec<usize> {
673 if *self.end() < 0 {
674 return Vec::new();
675 }
676 let start = (*self.start()).max(0) as usize;
677 let end = (*self.end() as usize + 1).min(count);
678 (start..end).collect()
679 }
680
681 fn is_contiguous(&self) -> bool {
682 true
683 }
684
685 #[cfg(feature = "ndarray")]
686 fn resolve_axis(&self, dim_size: usize) -> (usize, usize, bool) {
687 assert!(
688 *self.start() >= 0 && self.start() <= self.end() && (*self.end() as usize) < dim_size,
689 "axis selection: range {}..={} out of bounds (size {})",
690 self.start(), self.end(), dim_size
691 );
692 (*self.start() as usize, *self.end() as usize + 1, false)
693 }
694}