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}