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