byond/
lib.rs

1pub mod call;
2
3/// Define a function that BYOND can call into.
4///
5/// The list of arguments is always `&str`, and the code block must return an `impl AsRef<[u8]>`.
6/// If you want finer control over the arguments and return value,
7/// consider using `from_byond_args` and `return_to_byond()` directly.
8/// # Examples
9/// ```
10/// # use byond::byond;
11/// // Define a function called "test", taking two arguments.
12/// byond!(thing: one, two; {
13///     format!("{} + {}", one, two)
14/// });
15///
16/// # fn main(){}
17/// ```
18///
19/// The above code can be called with the following DM code:
20///
21/// ```dm
22/// // Produces "a + b" without quotes.
23/// world.log << call("test.dll", "thing")("a", "b")
24/// ```
25///
26/// # Panics
27/// Panics if the amount of arguments supplied by BYOND is too small.
28/// Note that extra arguments are ignored.
29/// Also panics if a NUL byte is attempted to be returned.
30#[macro_export]
31macro_rules! byond {
32    ( $n:ident ; $c:block ) => {
33        #[no_mangle]
34        pub unsafe extern "C" fn $n (__n: i32, __v: *const *const std::os::raw::c_char) -> *const std::os::raw::c_char {
35            $crate::call::return_to_byond((|| $c)()).unwrap()
36        }
37    };
38    ( $n:ident : $( $p:ident ),* ; $c:block ) => {
39        #[no_mangle]
40        pub unsafe extern "C" fn $n (__n: i32, __v: *const *const std::os::raw::c_char) -> *const std::os::raw::c_char {
41            let __args = $crate::call::from_byond_args(__n, __v);
42
43            let mut __count = 0;
44            $(
45                let $p: &str = &__args[__count];
46                __count += 1;
47            )*
48
49            let ret = (|| $c)();
50
51            $crate::call::return_to_byond(ret).unwrap()
52        }
53    };
54}