1use core::{fmt, slice};
5use gfxd_sys::{ffi, macro_info::gfxd_value_t, ptr::NonNullConst};
6
7use crate::{utils, ArgType, MacroId};
8
9const SIZEOF_GFX: usize = 8;
10
11pub struct MacroInfo {
13 _unit: (),
15}
16
17impl MacroInfo {
18 #[must_use]
20 pub(crate) const fn new() -> Self {
21 Self { _unit: () }
22 }
23
24 #[must_use]
26 pub fn macro_offset(&self) -> u32 {
27 let offset = unsafe { gfxd_sys::macro_info::gfxd_macro_offset() };
28 offset as _
29 }
30
31 #[must_use]
33 pub fn macro_packets(&self) -> u32 {
34 let offset = unsafe { gfxd_sys::macro_info::gfxd_macro_packets() };
35 offset as _
36 }
37
38 #[must_use]
45 pub fn macro_data(&self) -> &[u8] {
46 let data = unsafe { gfxd_sys::macro_info::gfxd_macro_data() };
47 let data_ptr = data.cast().as_ptr();
48 let byte_len = self.macro_packets() as usize * SIZEOF_GFX;
49
50 unsafe { slice::from_raw_parts(data_ptr, byte_len) }
53 }
54
55 #[must_use]
57 pub fn macro_id(&self) -> Option<MacroId> {
58 let macro_id_raw = unsafe { gfxd_sys::macro_info::gfxd_macro_id() };
59
60 MacroId::from_u32(macro_id_raw as _)
61 }
62
63 #[must_use]
75 pub fn macro_name(&mut self) -> Option<&str> {
76 let macro_name_raw = unsafe { gfxd_sys::macro_info::gfxd_macro_name() }?;
77
78 let macro_str = unsafe { utils::str_from_c_str(macro_name_raw) };
81
82 Some(macro_str)
83 }
84
85 #[must_use]
88 pub fn arg_count(&self) -> u32 {
89 let count = unsafe { gfxd_sys::macro_info::gfxd_arg_count() };
90
91 count as _
92 }
93
94 #[must_use]
98 pub fn arg_type(&self, arg_num: u32) -> Option<ArgType> {
99 if arg_num >= self.arg_count() {
100 return None;
101 }
102
103 let arg_type_raw = unsafe { gfxd_sys::macro_info::gfxd_arg_type(arg_num as _) };
104
105 ArgType::from_u32(arg_type_raw as _)
106 }
107
108 #[must_use]
115 pub fn arg_name(&self, arg_num: u32) -> Option<&str> {
116 if arg_num >= self.arg_count() {
117 return None;
118 }
119
120 let buf = unsafe { gfxd_sys::macro_info::gfxd_arg_name(arg_num as _) };
121
122 let name = unsafe { utils::str_from_c_str(buf) };
125
126 Some(name)
127 }
128
129 #[must_use]
131 pub fn arg_value(&self, arg_num: u32) -> Option<ArgValue> {
132 if arg_num >= self.arg_count() {
133 return None;
134 }
135
136 let raw_value = unsafe { gfxd_sys::macro_info::gfxd_arg_value(arg_num as _) };
137 let raw_fmt = unsafe { gfxd_sys::macro_info::gfxd_arg_fmt(arg_num as _) };
138
139 ArgValue::new(raw_fmt, raw_value)
140 }
141
142 #[must_use]
155 pub fn arg_valid(&self, arg_num: u32) -> Option<bool> {
156 if arg_num >= self.arg_count() {
157 return None;
158 }
159
160 let arg_valid = unsafe { gfxd_sys::macro_info::gfxd_arg_valid(arg_num as _) };
161
162 Some(arg_valid != 0)
163 }
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
168#[must_use]
169pub enum ArgValue {
170 I(i32),
172 U(u32),
174 F(f32),
176}
177
178impl ArgValue {
179 fn new(raw_fmt: ffi::c_int, raw_value: NonNullConst<gfxd_value_t>) -> Option<Self> {
180 let arg_value = unsafe { raw_value.as_ref() };
181
182 match raw_fmt as u32 {
183 gfxd_sys::macro_info::gfxd_argfmt_i => Some(Self::I(unsafe { arg_value.i })),
184 gfxd_sys::macro_info::gfxd_argfmt_u => Some(Self::U(unsafe { arg_value.u })),
185 gfxd_sys::macro_info::gfxd_argfmt_f => Some(Self::F(unsafe { arg_value.f })),
186 _ => None,
187 }
188 }
189
190 pub(crate) const fn to_gfxd_value(
191 self,
192 ) -> (
193 gfxd_sys::macro_info::ArgFmt,
194 gfxd_sys::macro_info::gfxd_value_t,
195 ) {
196 match self {
197 ArgValue::I(x) => (
198 gfxd_sys::macro_info::ArgFmt::gfxd_argfmt_i,
199 gfxd_sys::macro_info::gfxd_value_t { i: x },
200 ),
201 ArgValue::U(x) => (
202 gfxd_sys::macro_info::ArgFmt::gfxd_argfmt_u,
203 gfxd_sys::macro_info::gfxd_value_t { u: x },
204 ),
205 ArgValue::F(x) => (
206 gfxd_sys::macro_info::ArgFmt::gfxd_argfmt_f,
207 gfxd_sys::macro_info::gfxd_value_t { f: x },
208 ),
209 }
210 }
211}
212
213impl fmt::Display for ArgValue {
214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 match self {
216 ArgValue::I(x) => write!(f, "{}", x),
217 ArgValue::U(x) => write!(f, "0x{:08X}", x),
218 ArgValue::F(x) => write!(f, "{}", x),
219 }
220 }
221}