Skip to main content

graphrecords_query/registry/
emission.rs

1use 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}