Skip to main content

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}