1use interstice_abi::{
2 Authority, ModuleDependency, ModuleVisibility, NodeDependency, encode, pack_ptr_len,
3};
4
5#[macro_export]
6macro_rules! interstice_module {
7 () => {
8 interstice_module!(visibility: Private, authorities: []);
9 };
10
11 (visibility: $vis:ident) => {
12 interstice_module!(visibility: $vis, authorities: []);
13 };
14
15 (authorities: [$($auth:ident),* $(,)?]) => {
16 interstice_module!(visibility: Private, authorities: [$($auth),*]);
17 };
18
19 (visibility: $vis:ident, authorities: [$($auth:ident),* $(,)?]) => {
20 $(
21 interstice_module!(@impl_authority $auth);
22 )*
23
24 use std::str::FromStr;
26 #[global_allocator]
29 static ALLOC: interstice_sdk::wee_alloc::WeeAlloc =
30 interstice_sdk::wee_alloc::WeeAlloc::INIT;
31
32 #[unsafe(no_mangle)]
33 pub extern "C" fn alloc(size: i32) -> i32 {
34 let layout = std::alloc::Layout::from_size_align(size as usize, 8).unwrap();
35 unsafe { std::alloc::alloc(layout) as i32 }
36 }
37
38 #[unsafe(no_mangle)]
39 pub extern "C" fn dealloc(ptr: i32, size: i32) {
40 let layout = std::alloc::Layout::from_size_align(size as usize, 8).unwrap();
41 unsafe { std::alloc::dealloc(ptr as *mut u8, layout) }
42 }
43
44 #[$crate::init]
46 fn interstice_init() {
47 std::panic::set_hook(Box::new(|info| {
48 let msg = if let Some(s) = info.payload().downcast_ref::<&str>() {
49 *s
50 } else if let Some(s) = info.payload().downcast_ref::<String>() {
51 s.as_str()
52 } else {
53 "panic occurred"
54 };
55
56 interstice_sdk::host_calls::log(&format!("Panic Error: {}", msg));
58 }));
59 }
60
61 pub mod bindings {
63 include!(concat!(env!("OUT_DIR"), "/interstice_bindings.rs"));
64 }
65
66 const __INTERSTICE_MODULE_NAME: &str = env!("CARGO_PKG_NAME");
69 const __INTERSTICE_MODULE_VERSION: &str = env!("CARGO_PKG_VERSION");
70 const __INTERSTICE_VISIBILITY: ModuleVisibility = ModuleVisibility::$vis;
71 const __INTERSTICE_AUTHORITIES: &[interstice_abi::Authority] = &[
72 $(interstice_abi::Authority::$auth),*
73 ];
74
75 #[unsafe(no_mangle)]
76 pub extern "C" fn interstice_describe() -> i64 {
77 interstice_sdk::macros::describe_module(
78 __INTERSTICE_MODULE_NAME,
79 __INTERSTICE_MODULE_VERSION,
80 __INTERSTICE_VISIBILITY,
81 __INTERSTICE_AUTHORITIES,
82 bindings::__GET_INTERSTICE_MODULE_DEPENDENCIES(),
83 bindings::__GET_INTERSTICE_NODE_DEPENDENCIES()
84 )
85 }
86
87 };
88 (@impl_authority Input) => {
91 };
92
93 (@impl_authority Audio) => {
94 pub trait AudioExt {
95 fn audio(&self) -> Audio;
96 }
97
98 impl AudioExt for interstice_sdk::ReducerContext {
99 fn audio(&self) -> interstice_sdk::Audio {
100 interstice_sdk::Audio
101 }
102 }
103 };
104
105 (@impl_authority Gpu) => {
106 pub trait GpuExt {
107 fn gpu(&self) -> Gpu;
108 }
109
110 impl GpuExt for interstice_sdk::ReducerContext {
111 fn gpu(&self) -> interstice_sdk::Gpu {
112 interstice_sdk::Gpu
113 }
114 }
115 };
116
117 (@impl_authority File) => {
118 pub trait FileExt {
119 fn file(&self) -> File;
120 }
121
122 impl FileExt for interstice_sdk::ReducerContext {
123 fn file(&self) -> interstice_sdk::File {
124 interstice_sdk::File
125 }
126 }
127 };
128
129 (@impl_authority Module) => {
130 pub trait ModuleExt {
131 fn module(&self) -> ModuleAuthority;
132 }
133
134 impl ModuleExt for interstice_sdk::ReducerContext {
135 fn module(&self) -> interstice_sdk::ModuleAuthority {
136 interstice_sdk::ModuleAuthority
137 }
138 }
139 };
140}
141
142pub fn describe_module(
143 name: &str,
144 version: &str,
145 visibility: ModuleVisibility,
146 authorities: &'static [Authority],
147 module_dependencies: Vec<ModuleDependency>,
148 node_dependencies: Vec<NodeDependency>,
149) -> i64 {
150 let reducers = interstice_sdk_core::registry::collect_reducers();
151 let queries = interstice_sdk_core::registry::collect_queries();
152 let tables = interstice_sdk_core::registry::collect_tables();
153 let subscriptions = interstice_sdk_core::registry::collect_subscriptions();
154 let type_definitions = interstice_sdk_core::registry::collect_type_definitions();
155
156 let schema = interstice_abi::ModuleSchema {
157 abi_version: interstice_abi::ABI_VERSION,
158 name: name.to_string(),
159 version: version.into(),
160 visibility,
161 reducers,
162 queries,
163 tables,
164 subscriptions,
165 type_definitions,
166 authorities: authorities.to_vec(),
167 module_dependencies,
168 node_dependencies,
169 };
170
171 let bytes = encode(&schema).unwrap();
172 let len = bytes.len() as i32;
173 let ptr = Box::into_raw(bytes.into_boxed_slice()) as *mut u8 as i32;
174 return pack_ptr_len(ptr, len);
175}