Skip to main content

interstice_sdk/
macros.rs

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        // Global imports (for traits used in macros)
25        use std::str::FromStr;
26        // Use wee_alloc as the global allocator.
27
28        #[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        // Panic hook to log panics to host
45        #[$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                // send to host
57                interstice_sdk::host_calls::log(&format!("Panic Error: {}", msg));
58            }));
59        }
60
61        // BINDINGS
62        pub mod bindings {
63            include!(concat!(env!("OUT_DIR"), "/interstice_bindings.rs"));
64        }
65
66        // Module Schema Description
67
68        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    // Authorites calls
89
90    (@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}