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