harmos_domain/plugin/
mod.rs1mod requirement;
13
14pub use requirement::{Grant, Requirement, Requirements};
17
18pub trait Contribution: 'static {
37 const NAMESPACE: &'static str;
38 const SECTION: crate::inventory::Section;
39
40 fn register(registrar: &mut crate::Registrar) -> Result<(), crate::RegistrationError>;
41}
42
43pub trait Declared: Send + Sync + 'static {
44 const ID: &'static str;
45 const VERSION: &'static str;
46 const DESCRIPTION: &'static str;
47 const PROVIDES: &'static [crate::catalog::Node<crate::operations::WireDeclaration>];
48 const REQUIRES: &'static [crate::catalog::Node<Requirement>];
49 const CONTRIBUTIONS: &'static [crate::inventory::Section] = &[];
50 const LISTENERS: &'static [crate::catalog::Node<crate::listeners::Entry>] = &[];
51 const OBSERVERS: &'static [crate::catalog::Node<crate::inventory::observers::Entry>] = &[];
52 const STREAMS: &'static [crate::inventory::publications::Entry];
53
54 fn markers() -> Result<Vec<&'static [u8]>, crate::schema::graph::Error>;
55}
56
57pub fn schema_markers<P: Declared>(
63 mut carrier: Vec<&'static [u8]>, settings: &crate::config::SchemaSettings,
64) -> Result<Vec<&'static [u8]>, crate::schema::graph::Error> {
65 use crate::schema::Described;
66 use crate::schema::declaration::Definition;
67 use crate::schema::graph::Error;
68 let carrier_bytes = carrier.capacity().checked_mul(std::mem::size_of::<&[u8]>()).ok_or(Error::Budget)?;
69 if carrier_bytes > settings.preparation_bytes.get() {
70 return Err(Error::Budget);
71 }
72 let mut roots = Vec::new();
73 {
74 let mut append = |definition: &crate::operations::WireDeclaration| {
75 push_schema_root(&mut roots, definition.request, carrier_bytes, settings)?;
76 push_schema_root(&mut roots, definition.response, carrier_bytes, settings)?;
77 for item in [definition.input, definition.output].into_iter().flatten() {
78 push_schema_root(&mut roots, item, carrier_bytes, settings)?;
79 }
80 Ok(())
81 };
82 crate::catalog::try_for_each(P::PROVIDES, &mut append)?;
83 crate::catalog::try_for_each(P::REQUIRES, |requirement| append(&requirement.declaration))?;
84 if crate::catalog::count(P::OBSERVERS) != 0 {
85 append(&crate::operations::WireDeclaration::of::<crate::observers::Control>())?;
86 }
87 crate::catalog::try_for_each(P::LISTENERS, |listener| append(&listener.callback))?;
88 }
89 for stream in P::STREAMS {
90 push_schema_root(&mut roots, stream.row, carrier_bytes, settings)?;
91 }
92 crate::catalog::try_for_each(P::LISTENERS, |listener| push_schema_root(&mut roots, listener.source.row(), carrier_bytes, settings))?;
93 push_schema_root(
94 &mut roots,
95 <crate::operations::lifecycle::Initialize as crate::schema::Described>::DEFINITION,
96 carrier_bytes,
97 settings,
98 )?;
99 push_schema_root(&mut roots, <()>::DEFINITION, carrier_bytes, settings)?;
100 let retained = roots
101 .capacity()
102 .checked_mul(std::mem::size_of::<Definition>())
103 .and_then(|bytes| bytes.checked_add(carrier.capacity() * std::mem::size_of::<&[u8]>()))
104 .ok_or(Error::Budget)?;
105 let remaining = settings.preparation_bytes.get().checked_sub(retained).and_then(std::num::NonZeroUsize::new).ok_or(Error::Budget)?;
106 let allowance = crate::config::SchemaSettings { preparation_bytes: remaining, ..*settings };
107 let declarations = crate::schema::declaration::markers_many(roots, &allowance)?;
108 let output = carrier
109 .len()
110 .checked_add(declarations.len())
111 .and_then(|count| count.checked_mul(4 * std::mem::size_of::<&[u8]>()))
112 .and_then(|bytes| bytes.checked_add(declarations.capacity() * std::mem::size_of::<&[u8]>()))
113 .ok_or(Error::Budget)?;
114 if output > settings.preparation_bytes.get() {
115 return Err(Error::Budget);
116 }
117 carrier.extend(declarations);
118 Ok(carrier)
119}
120
121fn push_schema_root(
124 roots: &mut Vec<crate::schema::declaration::Definition>, definition: crate::schema::declaration::Definition, carrier_bytes: usize,
125 settings: &crate::config::SchemaSettings,
126) -> Result<(), crate::schema::graph::Error> {
127 use crate::schema::graph::Error;
128 let count = roots.len().checked_add(1).ok_or(Error::Budget)?;
129 let bytes = count
130 .checked_mul(4 * std::mem::size_of::<crate::schema::declaration::Definition>())
131 .and_then(|bytes| bytes.checked_add(carrier_bytes))
132 .ok_or(Error::Budget)?;
133 if bytes > settings.preparation_bytes.get() || count > settings.preparation_work.get() {
134 return Err(Error::Budget);
135 }
136 roots.push(definition);
137 Ok(())
138}
139
140