il2cpp_bridge_rs/structs/collections/list.rs
1//! IL2CPP List definition and operations
2use super::array::Il2cppArray;
3use std::ffi::c_void;
4use std::marker::PhantomData;
5
6#[repr(C)]
7pub struct Il2cppList<T: Copy> {
8 /// Pointer to the list class
9 pub klass: *mut c_void,
10 /// Monitor for synchronization
11 pub monitor: *mut c_void,
12 /// Internal array of items
13 pub items: *mut Il2cppArray<T>,
14 /// Number of elements in the list
15 pub size: i32,
16 /// Version of the list
17 pub version: i32,
18 _phantom: PhantomData<T>,
19}
20
21impl<T: Copy> Il2cppList<T> {
22 /// Gets the internal items array
23 ///
24 /// # Returns
25 /// * `Option<&Il2cppArray<T>>` - The underlying array, or None if null
26 pub fn items_array(&self) -> Option<&Il2cppArray<T>> {
27 if self.items.is_null() {
28 None
29 } else {
30 unsafe { Some(&*self.items) }
31 }
32 }
33
34 /// Gets the internal items array as mutable
35 ///
36 /// # Returns
37 /// * `Option<&mut Il2cppArray<T>>` - The underlying mutable array, or None if null
38 pub fn items_array_mut(&mut self) -> Option<&mut Il2cppArray<T>> {
39 if self.items.is_null() {
40 None
41 } else {
42 unsafe { Some(&mut *self.items) }
43 }
44 }
45
46 /// Gets the element at the specified index
47 ///
48 /// # Arguments
49 /// * `index` - The index of the element to retrieve
50 ///
51 /// # Returns
52 /// * `Option<T>` - The element if present and index is within bounds, otherwise None
53 pub fn get(&self, index: usize) -> Option<T> {
54 if index >= self.size as usize {
55 return None;
56 }
57 self.items_array().map(|arr| arr.get(index))
58 }
59
60 /// Alias for `get` that panics on out of bounds
61 ///
62 /// # Arguments
63 /// * `index` - The index of the element to retrieve
64 ///
65 /// # Returns
66 /// * `T` - The element at the specified index
67 ///
68 /// # Panics
69 /// Panics if the index is out of bounds or the item array is null.
70 pub fn at(&self, index: usize) -> T {
71 self.get(index).expect("Index out of bounds")
72 }
73
74 /// Sets the element at the specified index
75 ///
76 /// # Arguments
77 /// * `index` - The index where the value should be set
78 /// * `value` - The value to set
79 ///
80 /// # Returns
81 /// * `bool` - True if setting was successful, False if index out of bounds or array null
82 pub fn set(&mut self, index: usize, value: T) -> bool {
83 if index >= self.size as usize {
84 return false;
85 }
86 if let Some(arr) = self.items_array_mut() {
87 arr.set(index, value);
88 true
89 } else {
90 false
91 }
92 }
93
94 /// Converts the list to a Rust Vec
95 ///
96 /// # Returns
97 /// * `Vec<T>` - A new vector containing the list elements
98 pub fn to_vec(&self) -> Vec<T> {
99 let mut result = Vec::with_capacity(self.size as usize);
100 for i in 0..self.size as usize {
101 if let Some(item) = self.get(i) {
102 result.push(item);
103 }
104 }
105 result
106 }
107
108 /// Gets a pointer to the data array
109 ///
110 /// # Returns
111 /// * `Option<*const T>` - Pointer to the first element, or None
112 pub fn get_pointer(&self) -> Option<*const T> {
113 self.items_array().map(|arr| arr.get_pointer())
114 }
115
116 /// Returns an iterator over the list items
117 ///
118 /// # Returns
119 /// * `impl Iterator<Item = T> + '_` - An iterator yielding elements
120 pub fn iter(&self) -> impl Iterator<Item = T> + '_ {
121 (0..self.size as usize).filter_map(|i| self.get(i))
122 }
123}