graphrecords_query/capabilities/
sortable.rs1use crate::{ExpandedIndexOwned, ExpandedIndexReference, IndexDomain, Position};
2use graphrecords_core::graphrecord::{EdgeIndex, GraphRecordAttribute, GraphRecordValue};
3
4pub trait EnsureSortable: PartialOrd + Sized {
5 fn find_incomparable<'a>(values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)>
6 where
7 Self: 'a;
8}
9
10pub fn incomparable_with_first<'a, V: PartialOrd + 'a>(
11 mut values: impl Iterator<Item = &'a V>,
12) -> Option<(usize, usize)> {
13 let first = values.next()?;
14
15 values
16 .position(|value| value.partial_cmp(first).is_none())
17 .map(|position| (0, position + 1))
18}
19
20pub fn incomparable_pair<'a, V: PartialOrd + 'a>(
21 values: impl Iterator<Item = &'a V>,
22) -> Option<(usize, usize)> {
23 let values: Vec<_> = values.collect();
24
25 for first_position in 0..values.len() {
26 for second_position in (first_position + 1)..values.len() {
27 if values[first_position]
28 .partial_cmp(values[second_position])
29 .is_none()
30 {
31 return Some((first_position, second_position));
32 }
33 }
34 }
35
36 None
37}
38
39impl<T: EnsureSortable> EnsureSortable for &T {
40 fn find_incomparable<'a>(values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)>
41 where
42 Self: 'a,
43 {
44 T::find_incomparable(values.copied())
45 }
46}
47
48impl EnsureSortable for GraphRecordValue {
49 fn find_incomparable<'a>(values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)> {
50 incomparable_with_first(values)
51 }
52}
53
54impl EnsureSortable for GraphRecordAttribute {
55 fn find_incomparable<'a>(values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)> {
56 incomparable_with_first(values)
57 }
58}
59
60impl EnsureSortable for bool {
61 fn find_incomparable<'a>(_values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)> {
62 None
63 }
64}
65
66impl EnsureSortable for Position {
67 fn find_incomparable<'a>(_values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)> {
68 None
69 }
70}
71
72impl EnsureSortable for EdgeIndex {
73 fn find_incomparable<'a>(_values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)> {
74 None
75 }
76}
77
78impl<P, C> EnsureSortable for ExpandedIndexOwned<P, C>
79where
80 P: IndexDomain,
81 C: IndexDomain,
82 P::Owned: EnsureSortable,
83 C::Owned: EnsureSortable,
84{
85 fn find_incomparable<'a>(values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)>
86 where
87 Self: 'a,
88 {
89 incomparable_pair(values)
90 }
91}
92
93impl<'index, P, C> EnsureSortable for ExpandedIndexReference<'index, P, C>
94where
95 P: IndexDomain,
96 C: IndexDomain,
97 P::Index<'index>: EnsureSortable,
98 C::Index<'index>: EnsureSortable,
99{
100 fn find_incomparable<'a>(values: impl Iterator<Item = &'a Self>) -> Option<(usize, usize)>
101 where
102 Self: 'a,
103 {
104 incomparable_pair(values)
105 }
106}