samp_codegen/lib.rs
1//! Proc macros for the `rust-samp` toolkit.
2//!
3//! - `#[native]` — generates the `extern "C"` FFI wrapper for a Rust function,
4//! parsing arguments via [`AmxCell`] and handling the return value.
5//! - `initialize_plugin!` — generates the entry points required by the server
6//! (`Supports`/`Load`/`Unload`/`AmxLoad`/`AmxUnload`/`ProcessTick` on SA-MP
7//! and `ComponentEntryPoint` + vtable on Open Multiplayer), as well as native registration.
8//! - `#[derive(SampPlugin)]` — shortcut for an empty `impl SampPlugin for T {}`.
9//!
10//! This crate only compiles when loaded by `samp` via reexport — it has no
11//! runtime API of its own.
12//!
13//! [`AmxCell`]: samp::cell::AmxCell
14
15#![recursion_limit = "128"]
16
17use proc_macro::TokenStream;
18
19mod native;
20mod plugin;
21
22/// Prefix applied to the name of the `extern "C"` wrapper function generated by `#[native]`.
23/// Avoids collision with any function name declared by the developer.
24pub(crate) const NATIVE_PREFIX: &str = "__samp_native_";
25
26/// Prefix applied to the name of the native registration block in `initialize_plugin!`.
27pub(crate) const REG_PREFIX: &str = "__samp_reg_";
28
29/// Generates the `extern "C"` wrapper that reads the AMX argument table, parses
30/// it into the Rust types declared in the signature and invokes the marked method.
31#[proc_macro_attribute]
32pub fn native(args: TokenStream, input: TokenStream) -> TokenStream {
33 native::create_native(args, input)
34}
35
36/// Generates the entry points required by the server (SA-MP + Open Multiplayer), the Rust
37/// `IComponent` vtable and the registration of the plugin's native list.
38#[proc_macro]
39pub fn initialize_plugin(input: TokenStream) -> TokenStream {
40 plugin::create_plugin(input)
41}
42
43/// Generates `impl SampPlugin for T {}` with all methods using the default behavior
44/// (empty). Use for structs that do not need to customize any lifecycle callback —
45/// write the `impl SampPlugin` manually when some method needs custom logic.
46///
47/// ```rust,ignore
48/// use samp::prelude::*;
49///
50/// #[derive(SampPlugin)]
51/// struct SimplePlugin { counter: u32 }
52///
53/// // With logic in on_load → do not use the derive
54/// struct AdvancedPlugin;
55/// impl SampPlugin for AdvancedPlugin {
56/// fn on_load(&mut self) { println!("plugin loaded"); }
57/// }
58/// ```
59#[proc_macro_derive(SampPlugin)]
60pub fn derive_samp_plugin(input: TokenStream) -> TokenStream {
61 plugin::derive_samp_plugin(input)
62}