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
106pub fn describe_module(
107 name: &str,
108 version: &str,
109 visibility: ModuleVisibility,
110 authorities: &'static [Authority],
111 module_dependencies: Vec<ModuleDependency>,
112 node_dependencies: Vec<NodeDependency>,
113) -> i64 {
114 let reducers = interstice_sdk_core::registry::collect_reducers();
115 let tables = interstice_sdk_core::registry::collect_tables();
116 let subscriptions = interstice_sdk_core::registry::collect_subscriptions();
117 let type_definitions = interstice_sdk_core::registry::collect_type_definitions();
118
119 let schema = interstice_abi::ModuleSchema {
120 abi_version: interstice_abi::ABI_VERSION,
121 name: name.to_string(),
122 version: version.into(),
123 visibility,
124 reducers,
125 tables,
126 subscriptions,
127 type_definitions,
128 authorities: authorities.to_vec(),
129 module_dependencies,
130 node_dependencies,
131 };
132
133 let bytes = encode(&schema).unwrap();
134 let len = bytes.len() as i32;
135 let ptr = Box::into_raw(bytes.into_boxed_slice()) as *mut u8 as i32;
136 return pack_ptr_len(ptr, len);
137}