dear_imgui_rs/
internal.rs1#![allow(
7 clippy::cast_possible_truncation,
8 clippy::cast_sign_loss,
9 clippy::as_conversions
10)]
11use crate::sys;
12use std::ffi::c_int;
13use std::slice;
14
15#[repr(i32)]
17#[derive(Copy, Clone, Debug, Eq, PartialEq)]
18pub enum DataType {
19 I8 = sys::ImGuiDataType_S8 as i32,
20 U8 = sys::ImGuiDataType_U8 as i32,
21 I16 = sys::ImGuiDataType_S16 as i32,
22 U16 = sys::ImGuiDataType_U16 as i32,
23 I32 = sys::ImGuiDataType_S32 as i32,
24 U32 = sys::ImGuiDataType_U32 as i32,
25 I64 = sys::ImGuiDataType_S64 as i32,
26 U64 = sys::ImGuiDataType_U64 as i32,
27 F32 = sys::ImGuiDataType_Float as i32,
28 F64 = sys::ImGuiDataType_Double as i32,
29}
30
31pub unsafe trait DataTypeKind: Copy {
39 const KIND: DataType;
40}
41
42pub(crate) fn component_count_i32(caller: &str, len: usize) -> i32 {
43 assert!(len > 0, "{caller} requires at least one component");
44 i32::try_from(len).unwrap_or_else(|_| {
45 panic!("{caller} supports at most i32::MAX components");
46 })
47}
48
49pub(crate) fn plot_value_count_i32(caller: &str, len: usize) -> i32 {
50 i32::try_from(len).unwrap_or_else(|_| {
51 panic!("{caller} supports at most i32::MAX values");
52 })
53}
54
55pub(crate) fn len_i32(caller: &str, what: &str, len: usize) -> i32 {
56 i32::try_from(len).unwrap_or_else(|_| {
57 panic!("{caller} supports at most i32::MAX {what}");
58 })
59}
60
61unsafe impl DataTypeKind for i8 {
62 const KIND: DataType = DataType::I8;
63}
64unsafe impl DataTypeKind for u8 {
65 const KIND: DataType = DataType::U8;
66}
67unsafe impl DataTypeKind for i16 {
68 const KIND: DataType = DataType::I16;
69}
70unsafe impl DataTypeKind for u16 {
71 const KIND: DataType = DataType::U16;
72}
73unsafe impl DataTypeKind for i32 {
74 const KIND: DataType = DataType::I32;
75}
76unsafe impl DataTypeKind for u32 {
77 const KIND: DataType = DataType::U32;
78}
79unsafe impl DataTypeKind for i64 {
80 const KIND: DataType = DataType::I64;
81}
82unsafe impl DataTypeKind for u64 {
83 const KIND: DataType = DataType::U64;
84}
85unsafe impl DataTypeKind for f32 {
86 const KIND: DataType = DataType::F32;
87}
88unsafe impl DataTypeKind for f64 {
89 const KIND: DataType = DataType::F64;
90}
91
92unsafe impl DataTypeKind for usize {
93 #[cfg(target_pointer_width = "16")]
94 const KIND: DataType = DataType::U16;
95
96 #[cfg(target_pointer_width = "32")]
97 const KIND: DataType = DataType::U32;
98
99 #[cfg(target_pointer_width = "64")]
100 const KIND: DataType = DataType::U64;
101
102 #[cfg(not(any(
105 target_pointer_width = "16",
106 target_pointer_width = "32",
107 target_pointer_width = "64"
108 )))]
109 compile_error!(
110 "cannot impl DataTypeKind for usize: unsupported target pointer width. supported values are 16, 32, 64"
111 );
112}
113
114unsafe impl DataTypeKind for isize {
115 #[cfg(target_pointer_width = "16")]
116 const KIND: DataType = DataType::I16;
117
118 #[cfg(target_pointer_width = "32")]
119 const KIND: DataType = DataType::I32;
120
121 #[cfg(target_pointer_width = "64")]
122 const KIND: DataType = DataType::I64;
123
124 #[cfg(not(any(
127 target_pointer_width = "16",
128 target_pointer_width = "32",
129 target_pointer_width = "64"
130 )))]
131 compile_error!(
132 "cannot impl DataTypeKind for isize: unsupported target pointer width. supported values are 16, 32, 64"
133 );
134}
135
136#[repr(C)]
140pub struct ImVector<T> {
141 pub(crate) size: c_int,
142 pub(crate) capacity: c_int,
143 pub(crate) data: *mut T,
144}
145
146impl<T> ImVector<T> {
147 #[inline]
149 pub fn as_slice(&self) -> &[T] {
150 if self.size <= 0 || self.data.is_null() {
151 return &[];
152 }
153 let len = match usize::try_from(self.size) {
154 Ok(len) => len,
155 Err(_) => return &[],
156 };
157 unsafe { slice::from_raw_parts(self.data, len) }
158 }
159
160 #[inline]
162 pub fn as_slice_mut(&mut self) -> &mut [T] {
163 if self.size <= 0 || self.data.is_null() {
164 return &mut [];
165 }
166 let len = match usize::try_from(self.size) {
167 Ok(len) => len,
168 Err(_) => return &mut [],
169 };
170 unsafe { slice::from_raw_parts_mut(self.data, len) }
171 }
172
173 #[inline]
175 pub fn len(&self) -> usize {
176 if self.size <= 0 {
177 return 0;
178 }
179 usize::try_from(self.size).unwrap_or(0)
180 }
181
182 #[inline]
184 pub fn is_empty(&self) -> bool {
185 self.size <= 0
186 }
187}
188
189impl<T> Default for ImVector<T> {
190 fn default() -> Self {
191 Self {
192 size: 0,
193 capacity: 0,
194 data: std::ptr::null_mut(),
195 }
196 }
197}
198
199impl<T> ImVector<T> {
200 #[inline]
202 pub fn iter(&self) -> slice::Iter<'_, T> {
203 self.as_slice().iter()
204 }
205
206 #[inline]
208 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
209 self.as_slice_mut().iter_mut()
210 }
211}
212
213#[inline]
220pub unsafe fn imvector_cast_ref<T, R>(raw: &R) -> &ImVector<T> {
221 unsafe { &*(raw as *const R as *const ImVector<T>) }
222}
223
224#[inline]
230pub unsafe fn imvector_cast_mut<T, R>(raw: &mut R) -> &mut ImVector<T> {
231 unsafe { &mut *(raw as *mut R as *mut ImVector<T>) }
232}
233
234#[doc(alias = "UpdateHoveredWindowAndCaptureFlags")]
243pub fn update_hovered_window_and_capture_flags(mouse_pos: [f32; 2]) {
244 unsafe {
245 let pos = sys::ImVec2 {
246 x: mouse_pos[0],
247 y: mouse_pos[1],
248 };
249 sys::igUpdateHoveredWindowAndCaptureFlags(pos.into());
250 }
251}
252
253pub trait RawWrapper {
255 type Raw;
257 unsafe fn raw(&self) -> &Self::Raw;
264 unsafe fn raw_mut(&mut self) -> &mut Self::Raw;
271}
272
273pub unsafe trait RawCast<T>: Sized {
280 #[inline]
286 unsafe fn from_raw(raw: &T) -> &Self {
287 unsafe { &*(raw as *const _ as *const Self) }
288 }
289
290 #[inline]
296 unsafe fn from_raw_mut(raw: &mut T) -> &mut Self {
297 unsafe { &mut *(raw as *mut _ as *mut Self) }
298 }
299
300 #[inline]
306 unsafe fn raw(&self) -> &T {
307 unsafe { &*(self as *const _ as *const T) }
308 }
309
310 #[inline]
316 unsafe fn raw_mut(&mut self) -> &mut T {
317 unsafe { &mut *(self as *mut _ as *mut T) }
318 }
319}
320
321#[cfg(test)]
322mod tests {
323 use super::{component_count_i32, len_i32, plot_value_count_i32};
324
325 #[test]
326 fn component_count_rejects_zero_and_overflow() {
327 assert_eq!(component_count_i32("test", 1), 1);
328 assert!(std::panic::catch_unwind(|| component_count_i32("test", 0)).is_err());
329 assert!(
330 std::panic::catch_unwind(|| component_count_i32("test", (i32::MAX as usize) + 1))
331 .is_err()
332 );
333 }
334
335 #[test]
336 fn plot_value_count_allows_zero_but_rejects_overflow() {
337 assert_eq!(plot_value_count_i32("test", 0), 0);
338 assert_eq!(plot_value_count_i32("test", 1), 1);
339 assert!(
340 std::panic::catch_unwind(|| plot_value_count_i32("test", (i32::MAX as usize) + 1))
341 .is_err()
342 );
343 }
344
345 #[test]
346 fn len_i32_rejects_overflow() {
347 assert_eq!(len_i32("test", "items", 0), 0);
348 assert_eq!(len_i32("test", "items", 1), 1);
349 assert!(
350 std::panic::catch_unwind(|| len_i32("test", "items", (i32::MAX as usize) + 1)).is_err()
351 );
352 }
353}