classicube_sys\command/
owned_chat_command.rs

1use core::{ffi::CStr, ptr};
2
3use crate::{
4    bindings::{cc_string, Commands_Register},
5    std_types::{c_int, Box, CString, Vec},
6    ChatCommand, COMMAND_FLAG_SINGLEPLAYER_ONLY,
7};
8
9pub struct OwnedChatCommand {
10    pub name: Box<CStr>,
11    pub help: Vec<Box<CStr>>,
12    pub command: Box<ChatCommand>,
13}
14
15impl OwnedChatCommand {
16    pub fn new(
17        name: &str,
18        execute: unsafe extern "C" fn(args: *const cc_string, argsCount: c_int),
19        singleplayer_only: bool,
20        mut help: Vec<&str>,
21    ) -> Self {
22        let name = CString::new(name).unwrap().into_boxed_c_str();
23
24        let help: Vec<Box<CStr>> = help
25            .drain(..)
26            .map(|s| CString::new(s).unwrap().into_boxed_c_str())
27            .collect();
28
29        let help_array = [
30            #[allow(clippy::get_first)]
31            help.get(0).map(|cs| cs.as_ptr()).unwrap_or(ptr::null()),
32            help.get(1).map(|cs| cs.as_ptr()).unwrap_or(ptr::null()),
33            help.get(2).map(|cs| cs.as_ptr()).unwrap_or(ptr::null()),
34            help.get(3).map(|cs| cs.as_ptr()).unwrap_or(ptr::null()),
35            help.get(4).map(|cs| cs.as_ptr()).unwrap_or(ptr::null()),
36        ];
37
38        let command = Box::new(ChatCommand {
39            name: name.as_ptr(),
40            Execute: Some(execute),
41            flags: if singleplayer_only {
42                COMMAND_FLAG_SINGLEPLAYER_ONLY as _
43            } else {
44                0
45            },
46            help: help_array,
47            next: ptr::null_mut(),
48        });
49
50        Self {
51            name,
52            help,
53            command,
54        }
55    }
56
57    pub fn register(&mut self) {
58        let OwnedChatCommand { command, .. } = self;
59
60        unsafe {
61            Commands_Register(command.as_mut());
62        }
63    }
64}
65
66// #[test]
67// fn test_owned_chat_command() {
68//     extern "C" fn c_command_callback(_args: *const crate::String, _args_count: c_int) {}
69//     let mut cmd = OwnedChatCommand::new("Roll", c_command_callback, false, vec![]);
70//     cmd.as_mut().register();
71// }