harmos_domain/plugin/
mod.rs1mod requirement;
13
14pub use requirement::{Grant, Requirement, Requirements, aggregate, callee_count};
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(&mut roots, crate::model::operations::lifecycle::Action::Initialize.request(), carrier_bytes, settings)?;
94 push_schema_root(&mut roots, <()>::DEFINITION, carrier_bytes, settings)?;
95 let retained = roots
96 .capacity()
97 .checked_mul(std::mem::size_of::<Definition>())
98 .and_then(|bytes| bytes.checked_add(carrier.capacity() * std::mem::size_of::<&[u8]>()))
99 .ok_or(Error::Budget)?;
100 let remaining = settings.preparation_bytes.get().checked_sub(retained).and_then(std::num::NonZeroUsize::new).ok_or(Error::Budget)?;
101 let allowance = crate::config::SchemaSettings {
102 preparation_bytes: remaining,
103 ..*settings
104 };
105 let declarations = crate::schema::declaration::markers_many(roots, &allowance)?;
106 let output = carrier
107 .len()
108 .checked_add(declarations.len())
109 .and_then(|count| count.checked_mul(4 * std::mem::size_of::<&[u8]>()))
110 .and_then(|bytes| bytes.checked_add(declarations.capacity() * std::mem::size_of::<&[u8]>()))
111 .ok_or(Error::Budget)?;
112 if output > settings.preparation_bytes.get() {
113 return Err(Error::Budget);
114 }
115 carrier.extend(declarations);
116 Ok(carrier)
117}
118
119fn push_schema_root(
122 roots: &mut Vec<crate::schema::declaration::Definition>, definition: crate::schema::declaration::Definition, carrier_bytes: usize,
123 settings: &crate::config::SchemaSettings,
124) -> Result<(), crate::schema::graph::Error> {
125 use crate::schema::graph::Error;
126 let count = roots.len().checked_add(1).ok_or(Error::Budget)?;
127 let bytes = count
128 .checked_mul(4 * std::mem::size_of::<crate::schema::declaration::Definition>())
129 .and_then(|bytes| bytes.checked_add(carrier_bytes))
130 .ok_or(Error::Budget)?;
131 if bytes > settings.preparation_bytes.get() || count > settings.preparation_work.get() {
132 return Err(Error::Budget);
133 }
134 roots.push(definition);
135 Ok(())
136}
137
138