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 Gpu) => {
94 pub trait GpuExt {
95 fn gpu(&self) -> Gpu;
96 }
97
98 impl GpuExt for interstice_sdk::ReducerContext {
99 fn gpu(&self) -> interstice_sdk::Gpu {
100 interstice_sdk::Gpu
101 }
102 }
103 };
104
105 (@impl_authority File) => {
106 pub trait FileExt {
107 fn file(&self) -> File;
108 }
109
110 impl FileExt for interstice_sdk::ReducerContext {
111 fn file(&self) -> interstice_sdk::File {
112 interstice_sdk::File
113 }
114 }
115 };
116
117 (@impl_authority Module) => {
118 pub trait ModuleExt {
119 fn module(&self) -> ModuleAuthority;
120 }
121
122 impl ModuleExt for interstice_sdk::ReducerContext {
123 fn module(&self) -> interstice_sdk::ModuleAuthority {
124 interstice_sdk::ModuleAuthority
125 }
126 }
127 };
128}
129
130pub fn describe_module(
131 name: &str,
132 version: &str,
133 visibility: ModuleVisibility,
134 authorities: &'static [Authority],
135 module_dependencies: Vec<ModuleDependency>,
136 node_dependencies: Vec<NodeDependency>,
137) -> i64 {
138 let reducers = interstice_sdk_core::registry::collect_reducers();
139 let queries = interstice_sdk_core::registry::collect_queries();
140 let tables = interstice_sdk_core::registry::collect_tables();
141 let subscriptions = interstice_sdk_core::registry::collect_subscriptions();
142 let type_definitions = interstice_sdk_core::registry::collect_type_definitions();
143
144 let schema = interstice_abi::ModuleSchema {
145 abi_version: interstice_abi::ABI_VERSION,
146 name: name.to_string(),
147 version: version.into(),
148 visibility,
149 reducers,
150 queries,
151 tables,
152 subscriptions,
153 type_definitions,
154 authorities: authorities.to_vec(),
155 module_dependencies,
156 node_dependencies,
157 };
158
159 let bytes = encode(&schema).unwrap();
160 let len = bytes.len() as i32;
161 let ptr = Box::into_raw(bytes.into_boxed_slice()) as *mut u8 as i32;
162 return pack_ptr_len(ptr, len);
163}