Skip to main content

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 event;
20mod native;
21mod pawn_decl;
22mod plugin;
23
24/// Prefix applied to the name of the `extern "C"` wrapper function generated by `#[native]`.
25/// Avoids collision with any function name declared by the developer.
26pub(crate) const NATIVE_PREFIX: &str = "__samp_native_";
27
28/// Prefix applied to the name of the native registration block in `initialize_plugin!`.
29pub(crate) const REG_PREFIX: &str = "__samp_reg_";
30
31/// Prefix applied to the accessor that returns the native's Pawn declaration.
32pub(crate) const INC_PREFIX: &str = "__samp_inc_";
33
34/// Prefix applied to the handler wrapper generated by `#[event]`.
35pub(crate) const EVENT_PREFIX: &str = "__samp_event_";
36
37/// Prefix applied to the event registration block consumed by `initialize_plugin!`.
38pub(crate) const EVENT_REG_PREFIX: &str = "__samp_event_reg_";
39
40/// Generates the `extern "C"` wrapper that reads the AMX argument table, parses
41/// it into the Rust types declared in the signature and invokes the marked method.
42#[proc_macro_attribute]
43pub fn native(args: TokenStream, input: TokenStream) -> TokenStream {
44    native::create_native(args, input)
45}
46
47/// Generates the handler wrapper that observes a Pawn callback
48/// (`OnPlayerConnect`, `OnPlayerSpawn`, …). Parses the callback arguments into
49/// the Rust types declared in the signature and invokes the marked method when
50/// the callback runs in the gamemode's AMX. Register the handlers via
51/// `initialize_plugin!(events: [...])`.
52#[proc_macro_attribute]
53pub fn event(args: TokenStream, input: TokenStream) -> TokenStream {
54    event::create_event(args, input)
55}
56
57/// Generates the entry points required by the server (SA-MP + Open Multiplayer), the Rust
58/// `IComponent` vtable and the registration of the plugin's native list.
59#[proc_macro]
60pub fn initialize_plugin(input: TokenStream) -> TokenStream {
61    plugin::create_plugin(input)
62}
63
64/// Generates `impl SampPlugin for T {}` with all methods using the default behavior
65/// (empty). Use for structs that do not need to customize any lifecycle callback —
66/// write the `impl SampPlugin` manually when some method needs custom logic.
67///
68/// ```rust,ignore
69/// use samp::prelude::*;
70///
71/// #[derive(SampPlugin)]
72/// struct SimplePlugin { counter: u32 }
73///
74/// // With logic in on_load → do not use the derive
75/// struct AdvancedPlugin;
76/// impl SampPlugin for AdvancedPlugin {
77///     fn on_load(&mut self) { println!("plugin loaded"); }
78/// }
79/// ```
80#[proc_macro_derive(SampPlugin)]
81pub fn derive_samp_plugin(input: TokenStream) -> TokenStream {
82    plugin::derive_samp_plugin(input)
83}