1pub use crate::inventory::observers::Entry as ObserverEntry;
15pub use crate::inventory::publications::Entry as PublicationEntry;
16pub use crate::listeners::Entry as ListenerEntry;
17pub use crate::operations::{Entry as OperationEntry, WireDeclaration as WireEntry};
18pub use crate::plugin::Requirement as RequirementEntry;
19
20pub enum Node<E: 'static> {
39 Leaf(E),
40 Nested(&'static [Node<E>]),
41}
42
43pub trait Visitor {
46 type Entry: 'static;
47}
48
49pub trait Member<T>: Visitor {
50 const ENTRY: Self::Entry;
51}
52
53pub trait Projection<E> {
54 const LEN: usize;
55
56 fn try_for_each<F>(&self, visit: impl FnMut(&E) -> Result<(), F>) -> Result<(), F>;
57}
58
59pub trait InertCatalog<V: Visitor<Entry = E>, E: 'static> {
60 const ENTRIES: &'static [Node<E>];
61 const LEN: usize = count(Self::ENTRIES);
62}
63
64pub trait Catalog<V: Visitor> {
65 type Entries: Projection<V::Entry>;
66 const ENTRIES: Self::Entries;
67}
68
69pub trait Contains<T> {}
70
71impl<E, const N: usize> Projection<E> for [E; N] {
74 const LEN: usize = N;
75
76 fn try_for_each<F>(&self, mut visit: impl FnMut(&E) -> Result<(), F>) -> Result<(), F> {
77 for entry in self {
78 visit(entry)?;
79 }
80 Ok(())
81 }
82}
83
84impl<E> Projection<E> for () {
85 const LEN: usize = 0;
86
87 fn try_for_each<F>(&self, _: impl FnMut(&E) -> Result<(), F>) -> Result<(), F> {
88 Ok(())
89 }
90}
91
92impl<E, L: Projection<E>, R: Projection<E>> Projection<E> for (L, R) {
93 const LEN: usize = match L::LEN.checked_add(R::LEN) {
94 Some(len) => len,
95 None => panic!("catalog leaf count overflows usize"),
96 };
97
98 fn try_for_each<F>(&self, mut visit: impl FnMut(&E) -> Result<(), F>) -> Result<(), F> {
99 self.0.try_for_each(&mut visit)?;
100 self.1.try_for_each(visit)
101 }
102}
103
104impl<V: Visitor> Catalog<V> for () {
105 type Entries = [V::Entry; 0];
106 const ENTRIES: Self::Entries = [];
107}
108
109impl<V: Visitor<Entry = E>, E: 'static> InertCatalog<V, E> for () {
110 const ENTRIES: &'static [Node<E>] = &[];
111}
112
113pub const fn count<E>(nodes: &[Node<E>]) -> usize {
116 let mut len: usize = 0;
117 let mut index = 0;
118 while index < nodes.len() {
119 let added = match &nodes[index] {
120 Node::Leaf(_) => 1,
121 Node::Nested(nested) => count(nested),
122 };
123 len = match len.checked_add(added) {
124 Some(len) => len,
125 None => panic!("catalog leaf count overflows usize"),
126 };
127 index += 1;
128 }
129 len
130}
131
132pub fn try_for_each<E, F>(nodes: &[Node<E>], mut visit: impl FnMut(&E) -> Result<(), F>) -> Result<(), F> {
133 visit_nodes(nodes, &mut visit)
134}
135
136fn visit_nodes<E, F>(nodes: &[Node<E>], visit: &mut impl FnMut(&E) -> Result<(), F>) -> Result<(), F> {
139 for node in nodes {
140 match node {
141 Node::Leaf(entry) => visit(entry)?,
142 Node::Nested(nested) => visit_nodes(nested, visit)?,
143 }
144 }
145 Ok(())
146}
147
148