1use crate::{assert_dtype, get_itemsize, ConversionType, DTYPE, MUTABILITY, OWNERSHIP};
8use libc::{c_void, size_t};
9
10pub struct RustyDataContainer {
16 nitems: size_t,
18 itemsize: size_t,
20 capacity: size_t,
24 dtype: DTYPE,
26 is_owner: OWNERSHIP,
31 is_mutable: MUTABILITY,
34 data: *mut c_void,
36}
37
38impl RustyDataContainer {
39 pub fn from_slice<T: ConversionType>(slice: &[T]) -> Self {
41 Self {
42 nitems: slice.len(),
43 capacity: slice.len(),
44 itemsize: crate::get_size::<T>(),
45 dtype: crate::get_dtype::<T>(),
46 is_owner: OWNERSHIP::NotOwner,
47 is_mutable: MUTABILITY::NotMutable,
48 data: slice.as_ptr() as *mut c_void,
49 }
50 }
51 pub fn from_slice_mut<T: ConversionType>(slice: &mut [T]) -> Self {
53 Self {
54 nitems: slice.len(),
55 capacity: slice.len(),
56 itemsize: crate::get_size::<T>(),
57 dtype: crate::get_dtype::<T>(),
58 is_owner: OWNERSHIP::NotOwner,
59 is_mutable: MUTABILITY::Mutable,
60 data: slice.as_ptr() as *mut c_void,
61 }
62 }
63
64 pub fn to_box(self) -> Box<RustyDataContainer> {
66 Box::new(self)
67 }
68
69 pub unsafe fn to_vec<T: ConversionType>(mut self) -> Vec<T> {
70 assert_eq!(self.is_owner, OWNERSHIP::Owner);
71 assert_dtype::<T>(self.dtype);
72 self.is_owner = OWNERSHIP::NotOwner;
75 Vec::<T>::from_raw_parts(self.data as *mut T, self.nitems, self.capacity)
76 }
77
78 pub fn leak_mut(ptr: Option<Box<RustyDataContainer>>) -> &'static mut RustyDataContainer {
81 let ptr_ref = Box::leak(ptr.unwrap());
82 assert_eq!(ptr_ref.is_mutable, MUTABILITY::Mutable);
83 ptr_ref
84 }
85
86 pub fn leak(ptr: Option<Box<RustyDataContainer>>) -> &'static RustyDataContainer {
89 Box::leak(ptr.unwrap())
90 }
91
92 pub fn from_vec<T: ConversionType>(vec: Vec<T>) -> Self {
95 let nitems = vec.len();
96 let capacity = vec.capacity();
97 let data = vec.as_ptr() as *mut c_void;
98 std::mem::forget(vec);
99 Self {
100 nitems,
101 capacity,
102 itemsize: crate::get_size::<T>(),
103 dtype: crate::get_dtype::<T>(),
104 is_owner: OWNERSHIP::Owner,
105 is_mutable: MUTABILITY::Mutable,
106 data,
107 }
108 }
109
110 pub unsafe fn as_slice<T: ConversionType>(
113 ptr: Option<Box<RustyDataContainer>>,
114 ) -> &'static [T] {
115 let container = RustyDataContainer::leak(ptr);
116 assert_dtype::<T>(container.dtype);
117 std::slice::from_raw_parts::<'static, T>(container.data as *const T, container.nitems)
118 }
119
120 pub unsafe fn as_slice_mut<T: ConversionType>(
123 ptr: Option<Box<RustyDataContainer>>,
124 ) -> &'static mut [T] {
125 let container = RustyDataContainer::leak_mut(ptr);
126 assert_eq!(container.is_mutable, MUTABILITY::Mutable);
127 std::slice::from_raw_parts_mut::<'static, T>(container.data as *mut T, container.nitems)
128 }
129}
130
131impl Drop for RustyDataContainer {
132 fn drop(&mut self) {
135 if let OWNERSHIP::Owner = self.is_owner {
136 let len = self.nitems * self.itemsize;
137 let cap = self.capacity * self.itemsize;
138 let vec = unsafe { Vec::<u8>::from_raw_parts(self.data as *mut u8, len, cap) };
139 drop(vec);
140 }
141 }
142}
143
144#[no_mangle]
146pub extern "C" fn rusty_data_container_destroy(_: Option<Box<RustyDataContainer>>) {}
147
148#[no_mangle]
150pub extern "C" fn rusty_data_container_new_f32(nitems: size_t) -> Box<RustyDataContainer> {
151 RustyDataContainer::from_vec(vec![0 as f32; nitems]).to_box()
152}
153
154#[no_mangle]
156pub extern "C" fn rusty_data_container_new_f64(nitems: size_t) -> Box<RustyDataContainer> {
157 RustyDataContainer::from_vec(vec![0 as f64; nitems]).to_box()
158}
159
160#[no_mangle]
162pub extern "C" fn rusty_data_container_new_u8(nitems: size_t) -> Box<RustyDataContainer> {
163 RustyDataContainer::from_vec(vec![0 as u8; nitems]).to_box()
164}
165
166#[no_mangle]
168pub extern "C" fn rusty_data_container_new_u32(nitems: size_t) -> Box<RustyDataContainer> {
169 RustyDataContainer::from_vec(vec![0 as u32; nitems]).to_box()
170}
171
172#[no_mangle]
174pub extern "C" fn rusty_data_container_new_u64(nitems: size_t) -> Box<RustyDataContainer> {
175 RustyDataContainer::from_vec(vec![0 as u64; nitems]).to_box()
176}
177
178#[no_mangle]
180pub extern "C" fn rusty_data_container_new_i8(nitems: size_t) -> Box<RustyDataContainer> {
181 RustyDataContainer::from_vec(vec![0 as i8; nitems]).to_box()
182}
183
184#[no_mangle]
186pub extern "C" fn rusty_data_container_new_i32(nitems: size_t) -> Box<RustyDataContainer> {
187 RustyDataContainer::from_vec(vec![0 as i32; nitems]).to_box()
188}
189
190#[no_mangle]
192pub extern "C" fn rusty_data_container_new_i64(nitems: size_t) -> Box<RustyDataContainer> {
193 RustyDataContainer::from_vec(vec![0 as i64; nitems]).to_box()
194}
195
196#[no_mangle]
198pub extern "C" fn rusty_data_container_new_usize(nitems: size_t) -> Box<RustyDataContainer> {
199 RustyDataContainer::from_vec(vec![0 as usize; nitems]).to_box()
200}
201
202
203#[no_mangle]
205pub extern "C" fn rusty_data_container_get_nitems(ptr: Option<Box<RustyDataContainer>>) -> size_t {
206 RustyDataContainer::leak(ptr).nitems
207}
208
209#[no_mangle]
211pub extern "C" fn rusty_data_container_get_itemsize(
212 ptr: Option<Box<RustyDataContainer>>,
213) -> size_t {
214 RustyDataContainer::leak(ptr).itemsize
215}
216
217#[no_mangle]
219pub extern "C" fn rusty_data_container_get_dtype(ptr: Option<Box<RustyDataContainer>>) -> DTYPE {
220 RustyDataContainer::leak(ptr).dtype
221}
222
223#[no_mangle]
225pub extern "C" fn rusty_data_container_get_is_owner(
226 ptr: Option<Box<RustyDataContainer>>,
227) -> OWNERSHIP {
228 RustyDataContainer::leak(ptr).is_owner
229}
230
231#[no_mangle]
233pub extern "C" fn rusty_data_container_get_is_mutable(
234 ptr: Option<Box<RustyDataContainer>>,
235) -> MUTABILITY {
236 RustyDataContainer::leak(ptr).is_mutable
237}
238
239#[no_mangle]
241pub extern "C" fn rusty_data_container_get_data(
242 ptr: Option<Box<RustyDataContainer>>,
243) -> *mut c_void {
244 RustyDataContainer::leak(ptr).data
245}
246
247#[no_mangle]
248pub extern "C" fn new_from_pointer(
249 ptr: *mut c_void,
250 nitems: size_t,
251 dtype: DTYPE,
252 is_mutable: MUTABILITY,
253) -> Box<RustyDataContainer> {
254 RustyDataContainer {
255 nitems,
256 capacity: nitems,
257 itemsize: get_itemsize(dtype) as size_t,
258 dtype,
259 is_owner: OWNERSHIP::NotOwner,
260 is_mutable,
261 data: ptr,
262 }
263 .to_box()
264}
265