Skip to main content

graphrecords_query/registry/
capability.rs

1use super::descriptor::{DomainDescriptor, IndexDescriptor, ValueDescriptor, ValueRole};
2use crate::{
3    AttributeName, BareValueDomain, EdgeEndpointRole, EntityDomain, FailureKind, FailureKindValue,
4    FailureValue, IndexDomain, IndexValue, Mask, Positional, Scalar, ValueDomain,
5    capabilities::{
6        EnsureSortable, GroupingValue, IntValue, StringValue, ValueAbsolute, ValueAdd, ValueCast,
7        ValueCeil, ValueClip, ValueCubeRoot, ValueDivide, ValueEquality, ValueEquivalence,
8        ValueExponential, ValueFloor, ValueKindTest, ValueLogarithm, ValueMedian, ValueMode,
9        ValueModulo, ValueMultiply, ValueNegate, ValueOrdering, ValuePower, ValueRound,
10        ValueScalar, ValueScalarKindTest, ValueSign, ValueSquareRoot, ValueSubtract,
11    },
12    cast::{
13        Bool as BoolTarget, DateTime as DateTimeTarget, Duration as DurationTarget,
14        Float as FloatTarget, Int as IntTarget, String as StringTarget,
15    },
16    index::{EntityAttributes, GroupKey, IndicesInGroup},
17};
18use graphrecords_core::graphrecord::{EdgeIndex, GraphRecordValue, NodeIndex};
19use graphrecords_utils::aliases::{GrHashMap, GrHashSet};
20
21#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
22pub enum CapabilityIdentifier {
23    Absolute,
24    Add,
25    BareValue,
26    CastBool,
27    CastDateTime,
28    CastDuration,
29    CastFloat,
30    CastInt,
31    CastString,
32    Ceil,
33    Clip,
34    CubeRoot,
35    Divide,
36    Entity,
37    EntityAttributes,
38    Equality,
39    Equivalence,
40    Exponential,
41    Floor,
42    Grouping,
43    GroupKey,
44    IndicesInGroup,
45    Int,
46    KindTest,
47    Logarithm,
48    Median,
49    Mode,
50    Modulo,
51    Multiply,
52    Negate,
53    Ordering,
54    Power,
55    Round,
56    Scalar,
57    ScalarKindTest,
58    Sign,
59    Sortable,
60    SquareRoot,
61    String,
62    Subtract,
63}
64
65enum ValueCapabilityMember {
66    Value(DomainDescriptor),
67    Index(Option<DomainDescriptor>),
68    IndexCapable(CapabilityIdentifier),
69    EntityReference,
70    EntityReferenceCapable(CapabilityIdentifier),
71}
72
73impl ValueCapabilityMember {
74    fn matches(&self, value: &ValueDescriptor, registry: &CapabilityRegistry) -> bool {
75        match (self, value.role()) {
76            (Self::Value(domain), ValueRole::Value) => value.domain() == domain,
77            (Self::Index(None), ValueRole::Index(index)) => registry.contains_index(index),
78            (Self::Index(Some(domain)), ValueRole::Index(IndexDescriptor::Domain(candidate))) => {
79                candidate == domain
80            }
81            (Self::IndexCapable(capability), ValueRole::Index(index)) => {
82                registry.index_has(*capability, index)
83            }
84            (Self::EntityReference, ValueRole::EntityReference(index)) => {
85                registry.index_has(CapabilityIdentifier::Entity, index)
86            }
87            (Self::EntityReferenceCapable(capability), ValueRole::EntityReference(index)) => {
88                registry.index_has(CapabilityIdentifier::Entity, index)
89                    && registry.index_has(*capability, index)
90            }
91            _ => false,
92        }
93    }
94}
95
96#[derive(Default)]
97pub struct CapabilityRegistry {
98    index_domains: GrHashSet<DomainDescriptor>,
99    value_domains: GrHashSet<DomainDescriptor>,
100    value_members: GrHashMap<CapabilityIdentifier, Vec<ValueCapabilityMember>>,
101    index_members: GrHashMap<CapabilityIdentifier, GrHashSet<DomainDescriptor>>,
102    group_keys: GrHashMap<DomainDescriptor, IndexDescriptor>,
103}
104
105impl CapabilityRegistry {
106    #[must_use]
107    pub fn builtins() -> Self {
108        let mut registry = Self::default();
109
110        registry.register_index_domain::<GraphRecordValue>();
111        registry.register_index_domain::<bool>();
112        registry.register_index_domain::<AttributeName>();
113        registry.register_index_domain::<FailureKind>();
114        registry.register_index_domain::<Positional>();
115        registry.register_index_domain::<NodeIndex>();
116        registry.register_index_domain::<EdgeIndex>();
117        registry.register_index_domain::<EdgeEndpointRole>();
118
119        registry.register_value_domain::<Scalar>();
120        registry.register_value_domain::<Mask>();
121        registry.register_value_domain::<AttributeName>();
122        registry.register_value_domain::<FailureValue>();
123        registry.register_value_domain::<FailureKindValue>();
124
125        registry.register_value_add_domain::<Scalar>();
126        registry.register_value_add_domain::<AttributeName>();
127        registry.register_value_add_index::<Positional>();
128        registry.register_value_add_index::<NodeIndex>();
129        registry.register_value_add_index::<AttributeName>();
130        registry.register_value_add_index::<EdgeIndex>();
131        registry.register_value_add_index::<GraphRecordValue>();
132
133        registry.register_value_multiply_domain::<Scalar>();
134        registry.register_value_multiply_domain::<AttributeName>();
135        registry.register_value_multiply_index::<Positional>();
136        registry.register_value_multiply_index::<NodeIndex>();
137        registry.register_value_multiply_index::<AttributeName>();
138        registry.register_value_multiply_index::<EdgeIndex>();
139        registry.register_value_multiply_index::<GraphRecordValue>();
140
141        registry.register_value_scalar_domain::<Scalar>();
142        registry.register_value_scalar_index::<GraphRecordValue>();
143
144        registry.register_value_equivalence_domain::<Scalar>();
145        registry.register_value_equivalence_domain::<Mask>();
146        registry.register_value_equivalence_domain::<AttributeName>();
147        registry.register_value_equivalence_indices();
148        registry.register_value_equivalence_domain::<FailureKindValue>();
149
150        registry.register_value_median_domain::<Scalar>();
151        registry.register_value_median_index::<GraphRecordValue>();
152
153        registry.register_value_mode_domain::<Scalar>();
154        registry.register_value_mode_domain::<Mask>();
155        registry.register_value_mode_domain::<AttributeName>();
156        registry.register_value_mode_indices();
157
158        registry.register_value_ordering_domain::<Scalar>();
159        registry.register_value_ordering_domain::<AttributeName>();
160        registry.register_value_ordering_index::<Positional>();
161        registry.register_value_ordering_index::<NodeIndex>();
162        registry.register_value_ordering_index::<AttributeName>();
163        registry.register_value_ordering_index::<EdgeIndex>();
164        registry.register_value_ordering_index::<GraphRecordValue>();
165        registry.register_value_ordering_index::<bool>();
166        registry.register_value_ordering_indices();
167
168        registry.register_bare_value_domain::<Scalar>();
169        registry.register_bare_value_domain::<Mask>();
170        registry.register_bare_value_domain::<AttributeName>();
171        registry.register_bare_index_values();
172        registry.register_bare_entity_references();
173        registry.register_bare_value_domain::<FailureValue>();
174        registry.register_bare_value_domain::<FailureKindValue>();
175
176        registry.register_entity_domain::<EdgeIndex>();
177        registry.register_entity_domain::<NodeIndex>();
178
179        registry.register_group_key::<GraphRecordValue>();
180        registry.register_group_key::<bool>();
181        registry.register_group_key::<AttributeName>();
182        registry.register_group_key::<FailureKind>();
183        registry.register_group_key::<Positional>();
184        registry.register_group_key::<NodeIndex>();
185        registry.register_group_key::<EdgeIndex>();
186        registry.register_group_key::<EdgeEndpointRole>();
187
188        registry.register_entity_attributes::<NodeIndex>();
189        registry.register_entity_attributes::<EdgeIndex>();
190
191        registry.register_indices_in_group::<NodeIndex>();
192        registry.register_indices_in_group::<EdgeIndex>();
193
194        registry.register_index_sortable::<GraphRecordValue>();
195        registry.register_index_sortable::<bool>();
196        registry.register_index_sortable::<AttributeName>();
197        registry.register_index_sortable::<Positional>();
198        registry.register_index_sortable::<NodeIndex>();
199        registry.register_index_sortable::<EdgeIndex>();
200
201        registry.register_value_absolute_domain::<Scalar>();
202        registry.register_value_absolute_domain::<AttributeName>();
203        registry.register_value_absolute_index::<NodeIndex>();
204        registry.register_value_absolute_index::<AttributeName>();
205        registry.register_value_absolute_index::<GraphRecordValue>();
206
207        registry.register_value_cast_bool_domain::<Scalar>();
208        registry.register_value_cast_bool_index::<GraphRecordValue>();
209
210        registry.register_value_cast_date_time_domain::<Scalar>();
211        registry.register_value_cast_date_time_index::<GraphRecordValue>();
212
213        registry.register_value_cast_duration_domain::<Scalar>();
214        registry.register_value_cast_duration_index::<GraphRecordValue>();
215
216        registry.register_value_cast_float_domain::<Scalar>();
217        registry.register_value_cast_float_index::<GraphRecordValue>();
218
219        registry.register_value_cast_int_domain::<Scalar>();
220        registry.register_value_cast_int_domain::<AttributeName>();
221        registry.register_value_cast_int_index::<GraphRecordValue>();
222        registry.register_value_cast_int_index::<NodeIndex>();
223        registry.register_value_cast_int_index::<AttributeName>();
224
225        registry.register_value_cast_string_domain::<Scalar>();
226        registry.register_value_cast_string_domain::<AttributeName>();
227        registry.register_value_cast_string_index::<GraphRecordValue>();
228        registry.register_value_cast_string_index::<NodeIndex>();
229        registry.register_value_cast_string_index::<AttributeName>();
230
231        registry.register_value_ceil_domain::<Scalar>();
232        registry.register_value_ceil_index::<GraphRecordValue>();
233
234        registry.register_value_clip_domain::<Scalar>();
235        registry.register_value_clip_domain::<AttributeName>();
236        registry.register_value_clip_index::<Positional>();
237        registry.register_value_clip_index::<NodeIndex>();
238        registry.register_value_clip_index::<AttributeName>();
239        registry.register_value_clip_index::<EdgeIndex>();
240        registry.register_value_clip_index::<GraphRecordValue>();
241
242        registry.register_value_cube_root_domain::<Scalar>();
243        registry.register_value_cube_root_index::<GraphRecordValue>();
244
245        registry.register_value_divide_domain::<Scalar>();
246        registry.register_value_divide_index::<GraphRecordValue>();
247
248        registry.register_value_equality_domain::<Scalar>();
249        registry.register_value_equality_domain::<AttributeName>();
250        registry.register_value_equality_domain::<Mask>();
251        registry.register_value_equality_domain::<FailureKindValue>();
252        registry.register_value_equality_indices();
253
254        registry.register_value_exponential_domain::<Scalar>();
255        registry.register_value_exponential_index::<GraphRecordValue>();
256
257        registry.register_value_floor_domain::<Scalar>();
258        registry.register_value_floor_index::<GraphRecordValue>();
259
260        registry.register_value_grouping_domain::<Scalar>();
261        registry.register_value_grouping_domain::<Mask>();
262        registry.register_value_grouping_domain::<AttributeName>();
263        registry.register_value_grouping_domain::<FailureKindValue>();
264        registry.register_value_grouping_indices();
265        registry.register_value_grouping_entity_references();
266
267        registry.register_value_int_domain::<Scalar>();
268        registry.register_value_int_domain::<AttributeName>();
269        registry.register_value_int_index::<GraphRecordValue>();
270        registry.register_value_int_index::<NodeIndex>();
271        registry.register_value_int_index::<AttributeName>();
272        registry.register_value_int_index::<EdgeIndex>();
273        registry.register_value_int_index::<Positional>();
274
275        registry.register_value_kind_test_domain::<Scalar>();
276        registry.register_value_kind_test_domain::<AttributeName>();
277        registry.register_value_kind_test_index::<GraphRecordValue>();
278        registry.register_value_kind_test_index::<NodeIndex>();
279        registry.register_value_kind_test_index::<AttributeName>();
280
281        registry.register_value_logarithm_domain::<Scalar>();
282        registry.register_value_logarithm_index::<GraphRecordValue>();
283
284        registry.register_value_modulo_domain::<Scalar>();
285        registry.register_value_modulo_domain::<AttributeName>();
286        registry.register_value_modulo_index::<Positional>();
287        registry.register_value_modulo_index::<NodeIndex>();
288        registry.register_value_modulo_index::<AttributeName>();
289        registry.register_value_modulo_index::<EdgeIndex>();
290        registry.register_value_modulo_index::<GraphRecordValue>();
291
292        registry.register_value_negate_domain::<Scalar>();
293        registry.register_value_negate_domain::<AttributeName>();
294        registry.register_value_negate_index::<NodeIndex>();
295        registry.register_value_negate_index::<AttributeName>();
296        registry.register_value_negate_index::<GraphRecordValue>();
297
298        registry.register_value_power_domain::<Scalar>();
299        registry.register_value_power_domain::<AttributeName>();
300        registry.register_value_power_index::<Positional>();
301        registry.register_value_power_index::<NodeIndex>();
302        registry.register_value_power_index::<AttributeName>();
303        registry.register_value_power_index::<EdgeIndex>();
304        registry.register_value_power_index::<GraphRecordValue>();
305
306        registry.register_value_round_domain::<Scalar>();
307        registry.register_value_round_index::<GraphRecordValue>();
308
309        registry.register_value_scalar_kind_test_domain::<Scalar>();
310        registry.register_value_scalar_kind_test_index::<GraphRecordValue>();
311
312        registry.register_value_sign_domain::<Scalar>();
313        registry.register_value_sign_domain::<AttributeName>();
314        registry.register_value_sign_index::<NodeIndex>();
315        registry.register_value_sign_index::<AttributeName>();
316        registry.register_value_sign_index::<GraphRecordValue>();
317
318        registry.register_value_sortable_domain::<Scalar>();
319        registry.register_value_sortable_domain::<Mask>();
320        registry.register_value_sortable_domain::<AttributeName>();
321        registry.register_value_sortable_indices();
322
323        registry.register_value_square_root_domain::<Scalar>();
324        registry.register_value_square_root_index::<GraphRecordValue>();
325
326        registry.register_value_string_domain::<Scalar>();
327        registry.register_value_string_domain::<AttributeName>();
328        registry.register_value_string_index::<GraphRecordValue>();
329        registry.register_value_string_index::<NodeIndex>();
330        registry.register_value_string_index::<AttributeName>();
331
332        registry.register_value_subtract_domain::<Scalar>();
333        registry.register_value_subtract_domain::<AttributeName>();
334        registry.register_value_subtract_index::<Positional>();
335        registry.register_value_subtract_index::<NodeIndex>();
336        registry.register_value_subtract_index::<AttributeName>();
337        registry.register_value_subtract_index::<EdgeIndex>();
338        registry.register_value_subtract_index::<GraphRecordValue>();
339
340        registry
341    }
342
343    fn register_index_domain<I: IndexDomain>(&mut self) {
344        self.index_domains.insert(DomainDescriptor::of::<I>());
345    }
346
347    fn register_value_domain<V: ValueDomain>(&mut self) {
348        self.value_domains.insert(DomainDescriptor::of::<V>());
349    }
350
351    fn register_value_add_domain<V: ValueAdd>(&mut self) {
352        self.value_members
353            .entry(CapabilityIdentifier::Add)
354            .or_default()
355            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
356    }
357
358    fn register_value_add_index<I: IndexDomain>(&mut self)
359    where
360        IndexValue<I>: ValueAdd,
361    {
362        self.value_members
363            .entry(CapabilityIdentifier::Add)
364            .or_default()
365            .push(ValueCapabilityMember::Index(Some(
366                DomainDescriptor::of::<I>(),
367            )));
368    }
369
370    fn register_value_multiply_domain<V: ValueMultiply>(&mut self) {
371        self.value_members
372            .entry(CapabilityIdentifier::Multiply)
373            .or_default()
374            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
375    }
376
377    fn register_value_multiply_index<I: IndexDomain>(&mut self)
378    where
379        IndexValue<I>: ValueMultiply,
380    {
381        self.value_members
382            .entry(CapabilityIdentifier::Multiply)
383            .or_default()
384            .push(ValueCapabilityMember::Index(Some(
385                DomainDescriptor::of::<I>(),
386            )));
387    }
388
389    fn register_value_scalar_domain<V: ValueScalar>(&mut self) {
390        self.value_members
391            .entry(CapabilityIdentifier::Scalar)
392            .or_default()
393            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
394    }
395
396    fn register_value_scalar_index<I: IndexDomain>(&mut self)
397    where
398        IndexValue<I>: ValueScalar,
399    {
400        self.value_members
401            .entry(CapabilityIdentifier::Scalar)
402            .or_default()
403            .push(ValueCapabilityMember::Index(Some(
404                DomainDescriptor::of::<I>(),
405            )));
406    }
407
408    fn register_value_equivalence_domain<V: ValueEquivalence>(&mut self) {
409        self.value_members
410            .entry(CapabilityIdentifier::Equivalence)
411            .or_default()
412            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
413    }
414
415    fn register_value_equivalence_indices(&mut self) {
416        self.value_members
417            .entry(CapabilityIdentifier::Equivalence)
418            .or_default()
419            .push(ValueCapabilityMember::Index(None));
420    }
421
422    fn register_value_median_domain<V: ValueMedian>(&mut self) {
423        self.value_members
424            .entry(CapabilityIdentifier::Median)
425            .or_default()
426            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
427    }
428
429    fn register_value_median_index<I: IndexDomain>(&mut self)
430    where
431        IndexValue<I>: ValueMedian,
432    {
433        self.value_members
434            .entry(CapabilityIdentifier::Median)
435            .or_default()
436            .push(ValueCapabilityMember::Index(Some(
437                DomainDescriptor::of::<I>(),
438            )));
439    }
440
441    fn register_value_mode_domain<V: ValueMode>(&mut self) {
442        self.value_members
443            .entry(CapabilityIdentifier::Mode)
444            .or_default()
445            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
446    }
447
448    fn register_value_mode_indices(&mut self) {
449        self.value_members
450            .entry(CapabilityIdentifier::Mode)
451            .or_default()
452            .push(ValueCapabilityMember::Index(None));
453    }
454
455    fn register_value_ordering_domain<V: ValueOrdering>(&mut self) {
456        self.value_members
457            .entry(CapabilityIdentifier::Ordering)
458            .or_default()
459            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
460    }
461
462    fn register_value_ordering_index<I: IndexDomain>(&mut self)
463    where
464        IndexValue<I>: ValueOrdering,
465    {
466        self.index_members
467            .entry(CapabilityIdentifier::Ordering)
468            .or_default()
469            .insert(DomainDescriptor::of::<I>());
470    }
471
472    fn register_value_ordering_indices(&mut self) {
473        self.value_members
474            .entry(CapabilityIdentifier::Ordering)
475            .or_default()
476            .push(ValueCapabilityMember::IndexCapable(
477                CapabilityIdentifier::Ordering,
478            ));
479    }
480
481    fn register_bare_value_domain<V: BareValueDomain>(&mut self) {
482        self.value_members
483            .entry(CapabilityIdentifier::BareValue)
484            .or_default()
485            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
486    }
487
488    fn register_bare_index_values(&mut self) {
489        self.value_members
490            .entry(CapabilityIdentifier::BareValue)
491            .or_default()
492            .push(ValueCapabilityMember::Index(None));
493    }
494
495    fn register_bare_entity_references(&mut self) {
496        self.value_members
497            .entry(CapabilityIdentifier::BareValue)
498            .or_default()
499            .push(ValueCapabilityMember::EntityReference);
500    }
501
502    fn register_entity_domain<I: EntityDomain>(&mut self) {
503        self.index_members
504            .entry(CapabilityIdentifier::Entity)
505            .or_default()
506            .insert(DomainDescriptor::of::<I>());
507    }
508
509    fn register_group_key<I: GroupKey>(&mut self) {
510        self.index_members
511            .entry(CapabilityIdentifier::GroupKey)
512            .or_default()
513            .insert(DomainDescriptor::of::<I>());
514    }
515
516    fn register_entity_attributes<I: EntityAttributes>(&mut self) {
517        self.index_members
518            .entry(CapabilityIdentifier::EntityAttributes)
519            .or_default()
520            .insert(DomainDescriptor::of::<I>());
521    }
522
523    fn register_indices_in_group<I: IndicesInGroup>(&mut self) {
524        self.index_members
525            .entry(CapabilityIdentifier::IndicesInGroup)
526            .or_default()
527            .insert(DomainDescriptor::of::<I>());
528    }
529
530    fn register_index_sortable<I: IndexDomain>(&mut self)
531    where
532        for<'a> I::Index<'a>: EnsureSortable,
533    {
534        self.index_members
535            .entry(CapabilityIdentifier::Sortable)
536            .or_default()
537            .insert(DomainDescriptor::of::<I>());
538    }
539
540    fn register_value_absolute_domain<V: ValueAbsolute>(&mut self) {
541        self.value_members
542            .entry(CapabilityIdentifier::Absolute)
543            .or_default()
544            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
545    }
546
547    fn register_value_absolute_index<I: IndexDomain>(&mut self)
548    where
549        IndexValue<I>: ValueAbsolute,
550    {
551        self.value_members
552            .entry(CapabilityIdentifier::Absolute)
553            .or_default()
554            .push(ValueCapabilityMember::Index(Some(
555                DomainDescriptor::of::<I>(),
556            )));
557    }
558
559    fn register_value_cast_bool_domain<V: ValueCast<BoolTarget>>(&mut self) {
560        self.value_members
561            .entry(CapabilityIdentifier::CastBool)
562            .or_default()
563            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
564    }
565
566    fn register_value_cast_bool_index<I: IndexDomain>(&mut self)
567    where
568        IndexValue<I>: ValueCast<BoolTarget>,
569    {
570        self.value_members
571            .entry(CapabilityIdentifier::CastBool)
572            .or_default()
573            .push(ValueCapabilityMember::Index(Some(
574                DomainDescriptor::of::<I>(),
575            )));
576    }
577
578    fn register_value_cast_date_time_domain<V: ValueCast<DateTimeTarget>>(&mut self) {
579        self.value_members
580            .entry(CapabilityIdentifier::CastDateTime)
581            .or_default()
582            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
583    }
584
585    fn register_value_cast_date_time_index<I: IndexDomain>(&mut self)
586    where
587        IndexValue<I>: ValueCast<DateTimeTarget>,
588    {
589        self.value_members
590            .entry(CapabilityIdentifier::CastDateTime)
591            .or_default()
592            .push(ValueCapabilityMember::Index(Some(
593                DomainDescriptor::of::<I>(),
594            )));
595    }
596
597    fn register_value_cast_duration_domain<V: ValueCast<DurationTarget>>(&mut self) {
598        self.value_members
599            .entry(CapabilityIdentifier::CastDuration)
600            .or_default()
601            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
602    }
603
604    fn register_value_cast_duration_index<I: IndexDomain>(&mut self)
605    where
606        IndexValue<I>: ValueCast<DurationTarget>,
607    {
608        self.value_members
609            .entry(CapabilityIdentifier::CastDuration)
610            .or_default()
611            .push(ValueCapabilityMember::Index(Some(
612                DomainDescriptor::of::<I>(),
613            )));
614    }
615
616    fn register_value_cast_float_domain<V: ValueCast<FloatTarget>>(&mut self) {
617        self.value_members
618            .entry(CapabilityIdentifier::CastFloat)
619            .or_default()
620            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
621    }
622
623    fn register_value_cast_float_index<I: IndexDomain>(&mut self)
624    where
625        IndexValue<I>: ValueCast<FloatTarget>,
626    {
627        self.value_members
628            .entry(CapabilityIdentifier::CastFloat)
629            .or_default()
630            .push(ValueCapabilityMember::Index(Some(
631                DomainDescriptor::of::<I>(),
632            )));
633    }
634
635    fn register_value_cast_int_domain<V: ValueCast<IntTarget>>(&mut self) {
636        self.value_members
637            .entry(CapabilityIdentifier::CastInt)
638            .or_default()
639            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
640    }
641
642    fn register_value_cast_int_index<I: IndexDomain>(&mut self)
643    where
644        IndexValue<I>: ValueCast<IntTarget>,
645    {
646        self.value_members
647            .entry(CapabilityIdentifier::CastInt)
648            .or_default()
649            .push(ValueCapabilityMember::Index(Some(
650                DomainDescriptor::of::<I>(),
651            )));
652    }
653
654    fn register_value_cast_string_domain<V: ValueCast<StringTarget>>(&mut self) {
655        self.value_members
656            .entry(CapabilityIdentifier::CastString)
657            .or_default()
658            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
659    }
660
661    fn register_value_cast_string_index<I: IndexDomain>(&mut self)
662    where
663        IndexValue<I>: ValueCast<StringTarget>,
664    {
665        self.value_members
666            .entry(CapabilityIdentifier::CastString)
667            .or_default()
668            .push(ValueCapabilityMember::Index(Some(
669                DomainDescriptor::of::<I>(),
670            )));
671    }
672
673    fn register_value_ceil_domain<V: ValueCeil>(&mut self) {
674        self.value_members
675            .entry(CapabilityIdentifier::Ceil)
676            .or_default()
677            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
678    }
679
680    fn register_value_ceil_index<I: IndexDomain>(&mut self)
681    where
682        IndexValue<I>: ValueCeil,
683    {
684        self.value_members
685            .entry(CapabilityIdentifier::Ceil)
686            .or_default()
687            .push(ValueCapabilityMember::Index(Some(
688                DomainDescriptor::of::<I>(),
689            )));
690    }
691
692    fn register_value_clip_domain<V: ValueClip>(&mut self) {
693        self.value_members
694            .entry(CapabilityIdentifier::Clip)
695            .or_default()
696            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
697    }
698
699    fn register_value_clip_index<I: IndexDomain>(&mut self)
700    where
701        IndexValue<I>: ValueClip,
702    {
703        self.value_members
704            .entry(CapabilityIdentifier::Clip)
705            .or_default()
706            .push(ValueCapabilityMember::Index(Some(
707                DomainDescriptor::of::<I>(),
708            )));
709    }
710
711    fn register_value_cube_root_domain<V: ValueCubeRoot>(&mut self) {
712        self.value_members
713            .entry(CapabilityIdentifier::CubeRoot)
714            .or_default()
715            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
716    }
717
718    fn register_value_cube_root_index<I: IndexDomain>(&mut self)
719    where
720        IndexValue<I>: ValueCubeRoot,
721    {
722        self.value_members
723            .entry(CapabilityIdentifier::CubeRoot)
724            .or_default()
725            .push(ValueCapabilityMember::Index(Some(
726                DomainDescriptor::of::<I>(),
727            )));
728    }
729
730    fn register_value_divide_domain<V: ValueDivide>(&mut self) {
731        self.value_members
732            .entry(CapabilityIdentifier::Divide)
733            .or_default()
734            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
735    }
736
737    fn register_value_divide_index<I: IndexDomain>(&mut self)
738    where
739        IndexValue<I>: ValueDivide,
740    {
741        self.value_members
742            .entry(CapabilityIdentifier::Divide)
743            .or_default()
744            .push(ValueCapabilityMember::Index(Some(
745                DomainDescriptor::of::<I>(),
746            )));
747    }
748
749    fn register_value_equality_domain<V: ValueEquality>(&mut self) {
750        self.value_members
751            .entry(CapabilityIdentifier::Equality)
752            .or_default()
753            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
754    }
755
756    fn register_value_equality_indices(&mut self) {
757        self.value_members
758            .entry(CapabilityIdentifier::Equality)
759            .or_default()
760            .push(ValueCapabilityMember::Index(None));
761    }
762
763    fn register_value_exponential_domain<V: ValueExponential>(&mut self) {
764        self.value_members
765            .entry(CapabilityIdentifier::Exponential)
766            .or_default()
767            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
768    }
769
770    fn register_value_exponential_index<I: IndexDomain>(&mut self)
771    where
772        IndexValue<I>: ValueExponential,
773    {
774        self.value_members
775            .entry(CapabilityIdentifier::Exponential)
776            .or_default()
777            .push(ValueCapabilityMember::Index(Some(
778                DomainDescriptor::of::<I>(),
779            )));
780    }
781
782    fn register_value_floor_domain<V: ValueFloor>(&mut self) {
783        self.value_members
784            .entry(CapabilityIdentifier::Floor)
785            .or_default()
786            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
787    }
788
789    fn register_value_floor_index<I: IndexDomain>(&mut self)
790    where
791        IndexValue<I>: ValueFloor,
792    {
793        self.value_members
794            .entry(CapabilityIdentifier::Floor)
795            .or_default()
796            .push(ValueCapabilityMember::Index(Some(
797                DomainDescriptor::of::<I>(),
798            )));
799    }
800
801    fn register_value_grouping_domain<V: GroupingValue>(&mut self) {
802        self.value_members
803            .entry(CapabilityIdentifier::Grouping)
804            .or_default()
805            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
806        self.group_keys.insert(
807            DomainDescriptor::of::<V>(),
808            IndexDescriptor::domain::<V::Key>(),
809        );
810    }
811
812    fn register_value_grouping_indices(&mut self) {
813        self.value_members
814            .entry(CapabilityIdentifier::Grouping)
815            .or_default()
816            .push(ValueCapabilityMember::IndexCapable(
817                CapabilityIdentifier::GroupKey,
818            ));
819    }
820
821    fn register_value_grouping_entity_references(&mut self) {
822        self.value_members
823            .entry(CapabilityIdentifier::Grouping)
824            .or_default()
825            .push(ValueCapabilityMember::EntityReferenceCapable(
826                CapabilityIdentifier::GroupKey,
827            ));
828    }
829
830    fn register_value_int_domain<V: IntValue>(&mut self) {
831        self.value_members
832            .entry(CapabilityIdentifier::Int)
833            .or_default()
834            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
835    }
836
837    fn register_value_int_index<I: IndexDomain>(&mut self)
838    where
839        IndexValue<I>: IntValue,
840    {
841        self.value_members
842            .entry(CapabilityIdentifier::Int)
843            .or_default()
844            .push(ValueCapabilityMember::Index(Some(
845                DomainDescriptor::of::<I>(),
846            )));
847    }
848
849    fn register_value_kind_test_domain<V: ValueKindTest>(&mut self) {
850        self.value_members
851            .entry(CapabilityIdentifier::KindTest)
852            .or_default()
853            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
854    }
855
856    fn register_value_kind_test_index<I: IndexDomain>(&mut self)
857    where
858        IndexValue<I>: ValueKindTest,
859    {
860        self.value_members
861            .entry(CapabilityIdentifier::KindTest)
862            .or_default()
863            .push(ValueCapabilityMember::Index(Some(
864                DomainDescriptor::of::<I>(),
865            )));
866    }
867
868    fn register_value_logarithm_domain<V: ValueLogarithm>(&mut self) {
869        self.value_members
870            .entry(CapabilityIdentifier::Logarithm)
871            .or_default()
872            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
873    }
874
875    fn register_value_logarithm_index<I: IndexDomain>(&mut self)
876    where
877        IndexValue<I>: ValueLogarithm,
878    {
879        self.value_members
880            .entry(CapabilityIdentifier::Logarithm)
881            .or_default()
882            .push(ValueCapabilityMember::Index(Some(
883                DomainDescriptor::of::<I>(),
884            )));
885    }
886
887    fn register_value_modulo_domain<V: ValueModulo>(&mut self) {
888        self.value_members
889            .entry(CapabilityIdentifier::Modulo)
890            .or_default()
891            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
892    }
893
894    fn register_value_modulo_index<I: IndexDomain>(&mut self)
895    where
896        IndexValue<I>: ValueModulo,
897    {
898        self.value_members
899            .entry(CapabilityIdentifier::Modulo)
900            .or_default()
901            .push(ValueCapabilityMember::Index(Some(
902                DomainDescriptor::of::<I>(),
903            )));
904    }
905
906    fn register_value_negate_domain<V: ValueNegate>(&mut self) {
907        self.value_members
908            .entry(CapabilityIdentifier::Negate)
909            .or_default()
910            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
911    }
912
913    fn register_value_negate_index<I: IndexDomain>(&mut self)
914    where
915        IndexValue<I>: ValueNegate,
916    {
917        self.value_members
918            .entry(CapabilityIdentifier::Negate)
919            .or_default()
920            .push(ValueCapabilityMember::Index(Some(
921                DomainDescriptor::of::<I>(),
922            )));
923    }
924
925    fn register_value_power_domain<V: ValuePower>(&mut self) {
926        self.value_members
927            .entry(CapabilityIdentifier::Power)
928            .or_default()
929            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
930    }
931
932    fn register_value_power_index<I: IndexDomain>(&mut self)
933    where
934        IndexValue<I>: ValuePower,
935    {
936        self.value_members
937            .entry(CapabilityIdentifier::Power)
938            .or_default()
939            .push(ValueCapabilityMember::Index(Some(
940                DomainDescriptor::of::<I>(),
941            )));
942    }
943
944    fn register_value_round_domain<V: ValueRound>(&mut self) {
945        self.value_members
946            .entry(CapabilityIdentifier::Round)
947            .or_default()
948            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
949    }
950
951    fn register_value_round_index<I: IndexDomain>(&mut self)
952    where
953        IndexValue<I>: ValueRound,
954    {
955        self.value_members
956            .entry(CapabilityIdentifier::Round)
957            .or_default()
958            .push(ValueCapabilityMember::Index(Some(
959                DomainDescriptor::of::<I>(),
960            )));
961    }
962
963    fn register_value_scalar_kind_test_domain<V: ValueScalarKindTest>(&mut self) {
964        self.value_members
965            .entry(CapabilityIdentifier::ScalarKindTest)
966            .or_default()
967            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
968    }
969
970    fn register_value_scalar_kind_test_index<I: IndexDomain>(&mut self)
971    where
972        IndexValue<I>: ValueScalarKindTest,
973    {
974        self.value_members
975            .entry(CapabilityIdentifier::ScalarKindTest)
976            .or_default()
977            .push(ValueCapabilityMember::Index(Some(
978                DomainDescriptor::of::<I>(),
979            )));
980    }
981
982    fn register_value_sign_domain<V: ValueSign>(&mut self) {
983        self.value_members
984            .entry(CapabilityIdentifier::Sign)
985            .or_default()
986            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
987    }
988
989    fn register_value_sign_index<I: IndexDomain>(&mut self)
990    where
991        IndexValue<I>: ValueSign,
992    {
993        self.value_members
994            .entry(CapabilityIdentifier::Sign)
995            .or_default()
996            .push(ValueCapabilityMember::Index(Some(
997                DomainDescriptor::of::<I>(),
998            )));
999    }
1000
1001    fn register_value_sortable_domain<V: ValueDomain>(&mut self)
1002    where
1003        for<'a> V::Value<'a>: EnsureSortable,
1004    {
1005        self.value_members
1006            .entry(CapabilityIdentifier::Sortable)
1007            .or_default()
1008            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
1009    }
1010
1011    fn register_value_sortable_indices(&mut self) {
1012        self.value_members
1013            .entry(CapabilityIdentifier::Sortable)
1014            .or_default()
1015            .push(ValueCapabilityMember::IndexCapable(
1016                CapabilityIdentifier::Sortable,
1017            ));
1018    }
1019
1020    fn register_value_square_root_domain<V: ValueSquareRoot>(&mut self) {
1021        self.value_members
1022            .entry(CapabilityIdentifier::SquareRoot)
1023            .or_default()
1024            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
1025    }
1026
1027    fn register_value_square_root_index<I: IndexDomain>(&mut self)
1028    where
1029        IndexValue<I>: ValueSquareRoot,
1030    {
1031        self.value_members
1032            .entry(CapabilityIdentifier::SquareRoot)
1033            .or_default()
1034            .push(ValueCapabilityMember::Index(Some(
1035                DomainDescriptor::of::<I>(),
1036            )));
1037    }
1038
1039    fn register_value_string_domain<V: StringValue>(&mut self) {
1040        self.value_members
1041            .entry(CapabilityIdentifier::String)
1042            .or_default()
1043            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
1044    }
1045
1046    fn register_value_string_index<I: IndexDomain>(&mut self)
1047    where
1048        IndexValue<I>: StringValue,
1049    {
1050        self.value_members
1051            .entry(CapabilityIdentifier::String)
1052            .or_default()
1053            .push(ValueCapabilityMember::Index(Some(
1054                DomainDescriptor::of::<I>(),
1055            )));
1056    }
1057
1058    fn register_value_subtract_domain<V: ValueSubtract>(&mut self) {
1059        self.value_members
1060            .entry(CapabilityIdentifier::Subtract)
1061            .or_default()
1062            .push(ValueCapabilityMember::Value(DomainDescriptor::of::<V>()));
1063    }
1064
1065    fn register_value_subtract_index<I: IndexDomain>(&mut self)
1066    where
1067        IndexValue<I>: ValueSubtract,
1068    {
1069        self.value_members
1070            .entry(CapabilityIdentifier::Subtract)
1071            .or_default()
1072            .push(ValueCapabilityMember::Index(Some(
1073                DomainDescriptor::of::<I>(),
1074            )));
1075    }
1076
1077    #[must_use]
1078    pub fn value_has(&self, capability: CapabilityIdentifier, value: &ValueDescriptor) -> bool {
1079        self.value_members
1080            .get(&capability)
1081            .is_some_and(|members| members.iter().any(|member| member.matches(value, self)))
1082    }
1083
1084    #[must_use]
1085    pub fn group_key(&self, value: &ValueDescriptor) -> Option<IndexDescriptor> {
1086        match value.role() {
1087            ValueRole::Value => self.group_keys.get(value.domain()).cloned(),
1088            ValueRole::Index(index) | ValueRole::EntityReference(index) => Some(index.clone()),
1089            ValueRole::Unit => None,
1090        }
1091    }
1092
1093    #[must_use]
1094    pub fn index_has(&self, capability: CapabilityIdentifier, index: &IndexDescriptor) -> bool {
1095        match (capability, index) {
1096            (
1097                CapabilityIdentifier::GroupKey
1098                | CapabilityIdentifier::Ordering
1099                | CapabilityIdentifier::Sortable,
1100                IndexDescriptor::Expanded { parent, child },
1101            ) => self.index_has(capability, parent) && self.index_has(capability, child),
1102            (_, IndexDescriptor::Expanded { .. } | IndexDescriptor::ExpandedSource { .. }) => false,
1103            (_, IndexDescriptor::Domain(domain)) => self
1104                .index_members
1105                .get(&capability)
1106                .is_some_and(|members| members.contains(domain)),
1107        }
1108    }
1109
1110    pub(super) fn contains_index(&self, index: &IndexDescriptor) -> bool {
1111        match index {
1112            IndexDescriptor::Domain(domain) => self.index_domains.contains(domain),
1113            IndexDescriptor::Expanded { parent, child } => {
1114                self.contains_index(parent) && self.contains_index(child)
1115            }
1116            IndexDescriptor::ExpandedSource { .. } => false,
1117        }
1118    }
1119
1120    pub(super) fn contains_value(&self, value: &ValueDescriptor) -> bool {
1121        match value.role() {
1122            ValueRole::Value => self.value_domains.contains(value.domain()),
1123            ValueRole::Index(index) => self.contains_index(index),
1124            ValueRole::EntityReference(index) => {
1125                self.index_has(CapabilityIdentifier::Entity, index)
1126            }
1127            ValueRole::Unit => true,
1128        }
1129    }
1130}