hara_native/lang/protocol/
declarations.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum ProtocolAvailability {
3 Portable,
4 CapabilityGated,
5 InventoryOnly,
6}
7
8impl ProtocolAvailability {
9 pub fn is_guest_visible(self) -> bool {
10 !matches!(self, Self::InventoryOnly)
11 }
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum ProtocolArity {
16 Fixed(usize),
17 Variadic {
18 minimum: usize,
19 maximum: Option<usize>,
20 },
21}
22
23impl ProtocolArity {
24 pub fn guest_arity(self) -> usize {
25 match self {
26 Self::Fixed(arity) => arity,
27 Self::Variadic { .. } => usize::MAX,
28 }
29 }
30
31 pub fn range(self) -> (usize, Option<usize>) {
32 match self {
33 Self::Fixed(arity) => (arity, Some(arity)),
34 Self::Variadic { minimum, maximum } => (minimum, maximum),
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub struct ProtocolMethodDeclaration {
41 pub name: &'static str,
42 pub rust_name: &'static str,
43 pub arity: ProtocolArity,
44 pub whole_wasm: bool,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub struct ProtocolDeclaration {
49 pub namespace: &'static str,
50 pub name: &'static str,
51 pub parents: &'static [&'static str],
52 pub availability: ProtocolAvailability,
53 pub capability: Option<&'static str>,
54 pub methods: &'static [ProtocolMethodDeclaration],
55}
56
57impl ProtocolDeclaration {
58 pub fn qualified_name(self) -> String {
59 format!("{}/{}", self.namespace, self.name)
60 }
61
62 pub fn runtime_name(self) -> String {
63 format!("{}.{}", self.namespace, self.name)
64 }
65
66 pub fn method(self, name: &str) -> Option<ProtocolMethodDeclaration> {
67 self.methods
68 .iter()
69 .copied()
70 .find(|method| method.name == name)
71 }
72}
73
74inventory::collect!(ProtocolDeclaration);
75
76static PROTOCOL_DECLARATIONS: std::sync::OnceLock<Vec<ProtocolDeclaration>> =
77 std::sync::OnceLock::new();
78
79pub fn protocol_declarations() -> &'static [ProtocolDeclaration] {
80 PROTOCOL_DECLARATIONS
81 .get_or_init(|| {
82 let mut declarations = inventory::iter::<ProtocolDeclaration>
83 .into_iter()
84 .copied()
85 .collect::<Vec<_>>();
86 declarations.sort_by_key(|declaration| (declaration.namespace, declaration.name));
87 declarations
88 })
89 .as_slice()
90}
91
92pub fn find_protocol(name: &str) -> Option<ProtocolDeclaration> {
93 protocol_declarations().iter().copied().find(|protocol| {
94 protocol.name == name
95 || protocol.qualified_name() == name
96 || protocol.runtime_name() == name
97 })
98}