Skip to main content

samp_sdk/
encoding.rs

1//! Global encoding for Rust <-> AMX conversion (only with the `encoding` feature).
2//!
3//! The original SA-MP operates on 8-bit encodings (Western Windows-1252 by
4//! default, Windows-1251 for Cyrillic on Russian servers). This module lets the
5//! plugin configure the encoding once in `on_load` — after that, `AmxString`
6//! decodes and [`Buffer::write_str`] encodes using it automatically.
7//!
8//! [`Buffer::write_str`]: crate::cell::Buffer::write_str
9
10use encoding_rs::Encoding;
11pub use encoding_rs::{WINDOWS_1251, WINDOWS_1252};
12use std::sync::atomic::{AtomicPtr, Ordering};
13
14static DEFAULT_ENCODING: AtomicPtr<Encoding> =
15    AtomicPtr::new(std::ptr::from_ref::<Encoding>(WINDOWS_1252).cast_mut());
16
17/// Sets the global encoding used in every AMX string conversion.
18///
19/// Call once during plugin initialization (`on_load`). Later changes are
20/// visible immediately to any thread (`Ordering::Release`/`Acquire`).
21pub fn set_default_encoding(encoding: &'static Encoding) {
22    DEFAULT_ENCODING.store(
23        std::ptr::from_ref::<Encoding>(encoding).cast_mut(),
24        Ordering::Release,
25    );
26}
27
28pub(crate) fn get() -> &'static Encoding {
29    unsafe { &*DEFAULT_ENCODING.load(Ordering::Acquire) }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn default_encoding_is_windows_1252() {
38        let enc = get();
39        assert_eq!(enc.name(), WINDOWS_1252.name());
40    }
41
42    #[test]
43    fn set_and_get_encoding() {
44        set_default_encoding(WINDOWS_1251);
45        let enc = get();
46        assert_eq!(enc.name(), WINDOWS_1251.name());
47
48        // restore default
49        set_default_encoding(WINDOWS_1252);
50        let enc = get();
51        assert_eq!(enc.name(), WINDOWS_1252.name());
52    }
53}