graphrecords_query/registry/
emission.rs1use super::{
2 descriptor::{ArityDescriptor, RetentionDescriptor},
3 manifest::describe::{DescribeArity, DescribeEmission},
4};
5use crate::{
6 Arity, Definite, Multiple, Ordered, Single, Unordered,
7 element::{Dropping, ElementEmission, Expanding, Preserving},
8};
9use graphrecords_utils::aliases::GrHashMap;
10
11#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
12pub enum EmissionKind {
13 Preserving,
14 Dropping,
15 ExpandingOrdered,
16 ExpandingUnordered,
17}
18
19#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
20pub enum EmissionSpec {
21 Fixed(EmissionKind),
22 OfArgument,
23}
24
25#[derive(Default)]
26pub struct OutArityTable {
27 cells: GrHashMap<(EmissionSpec, ArityDescriptor), ArityDescriptor>,
28}
29
30impl OutArityTable {
31 pub(super) fn builtins() -> Self {
32 let mut table = Self::default();
33
34 table.insert_row::<Preserving>();
35 table.insert_row::<Dropping>();
36 table.insert_row::<Expanding<Ordered>>();
37 table.insert_row::<Expanding<Unordered>>();
38
39 table
40 }
41
42 fn insert_row<E>(&mut self)
43 where
44 E: ElementEmission + DescribeEmission,
45 E::OutArity<Multiple<Ordered>>: DescribeArity,
46 E::OutArity<Multiple<Unordered>>: DescribeArity,
47 E::OutArity<Single>: DescribeArity,
48 E::OutArity<Definite>: DescribeArity,
49 {
50 self.insert_cell::<E, Multiple<Ordered>>();
51 self.insert_cell::<E, Multiple<Unordered>>();
52 self.insert_cell::<E, Single>();
53 self.insert_cell::<E, Definite>();
54 }
55
56 fn insert_cell<E, C>(&mut self)
57 where
58 E: ElementEmission + DescribeEmission,
59 C: Arity + DescribeArity,
60 E::OutArity<C>: DescribeArity,
61 {
62 self.cells.insert(
63 (E::emission_spec(), C::arity_descriptor()),
64 <E::OutArity<C> as DescribeArity>::arity_descriptor(),
65 );
66 }
67
68 pub(super) fn resolve(
69 &self,
70 emission: EmissionSpec,
71 arity: ArityDescriptor,
72 retention: RetentionDescriptor,
73 ) -> ArityDescriptor {
74 let emission = match emission {
75 EmissionSpec::Fixed(_) => emission,
76 EmissionSpec::OfArgument => EmissionSpec::Fixed(match retention {
77 RetentionDescriptor::Preserving => EmissionKind::Preserving,
78 RetentionDescriptor::Dropping => EmissionKind::Dropping,
79 }),
80 };
81
82 *self.cells.get(&(emission, arity)).unwrap_or_else(|| {
83 panic!("registry has no materialized out arity for {emission:?} applied to {arity:?}")
84 })
85 }
86}