1use crate::error::Error;
20use crate::object;
21use crate::type_traits::AnyCompatible;
22use tvm_ffi_sys::TVMFFITypeIndex as TypeIndex;
23use tvm_ffi_sys::{TVMFFIAny, TVMFFIAnyViewToOwnedAny};
24
25#[derive(Copy, Clone)]
27#[repr(C)]
28pub struct AnyView<'a> {
29 data: TVMFFIAny,
30 _phantom: std::marker::PhantomData<&'a ()>,
32}
33
34#[repr(C)]
36pub struct Any {
37 data: TVMFFIAny,
38}
39
40impl<'a> AnyView<'a> {
44 pub fn new() -> Self {
45 Self {
46 data: TVMFFIAny::new(),
47 _phantom: std::marker::PhantomData,
48 }
49 }
50
51 #[inline]
52 pub fn type_index(&self) -> i32 {
53 self.data.type_index
54 }
55
56 #[inline]
65 pub fn try_as<T>(&self) -> Option<T>
66 where
67 T: AnyCompatible,
68 {
69 unsafe {
70 if T::check_any_strict(&self.data) {
71 Some(T::copy_from_any_view_after_check(&self.data))
72 } else {
73 None
74 }
75 }
76 }
77
78 pub fn debug_strong_count(&self) -> Option<usize> {
82 unsafe {
83 if self.data.type_index >= TypeIndex::kTVMFFIStaticObjectBegin as i32 {
84 Some(object::unsafe_::strong_count(self.data.data_union.v_obj))
85 } else {
86 None
87 }
88 }
89 }
90}
91
92impl<'a, T: AnyCompatible> From<&'a T> for AnyView<'a> {
93 #[inline]
94 fn from(value: &'a T) -> Self {
95 unsafe {
96 let mut data = TVMFFIAny::new();
97 T::copy_to_any_view(&value, &mut data);
98 Self {
99 data: data,
100 _phantom: std::marker::PhantomData,
101 }
102 }
103 }
104}
105
106impl Default for AnyView<'_> {
107 fn default() -> Self {
108 Self::new()
109 }
110}
111
112pub struct TryFromTemp<T> {
117 value: T,
118}
119
120impl<T> TryFromTemp<T> {
121 #[inline(always)]
123 pub fn new(value: T) -> Self {
124 Self { value }
125 }
126
127 #[inline(always)]
129 pub fn into_value(this: Self) -> T {
130 this.value
131 }
132}
133
134impl Any {
138 pub fn new() -> Self {
139 Self {
140 data: TVMFFIAny::new(),
141 }
142 }
143 #[inline]
144 pub fn type_index(&self) -> i32 {
145 self.data.type_index
146 }
147 #[inline]
160 pub fn try_as<T>(&self) -> Option<T>
161 where
162 T: AnyCompatible,
163 {
164 unsafe {
165 if T::check_any_strict(&self.data) {
166 Some(T::copy_from_any_view_after_check(&self.data))
167 } else {
168 None
169 }
170 }
171 }
172
173 #[inline]
174 pub unsafe fn as_data_ptr(&mut self) -> *mut TVMFFIAny {
175 &mut self.data
176 }
177
178 #[inline]
179 pub unsafe fn into_raw_ffi_any(this: Self) -> TVMFFIAny {
180 this.data
181 }
182
183 #[inline]
184 pub unsafe fn from_raw_ffi_any(data: TVMFFIAny) -> Self {
185 Self { data }
186 }
187
188 pub fn debug_strong_count(&self) -> Option<usize> {
192 unsafe {
193 if self.data.type_index >= TypeIndex::kTVMFFIStaticObjectBegin as i32 {
194 Some(object::unsafe_::strong_count(self.data.data_union.v_obj))
195 } else {
196 None
197 }
198 }
199 }
200}
201
202impl Default for Any {
203 fn default() -> Self {
204 Self::new()
205 }
206}
207
208impl Clone for Any {
209 #[inline]
210 fn clone(&self) -> Self {
211 if self.data.type_index >= TypeIndex::kTVMFFIStaticObjectBegin as i32 {
212 unsafe { object::unsafe_::inc_ref(self.data.data_union.v_obj) }
213 }
214 Self { data: self.data }
215 }
216}
217
218impl Drop for Any {
219 #[inline]
220 fn drop(&mut self) {
221 if self.data.type_index >= TypeIndex::kTVMFFIStaticObjectBegin as i32 {
222 unsafe { object::unsafe_::dec_ref(self.data.data_union.v_obj) }
223 }
224 }
225}
226
227impl<'a> From<&'a Any> for AnyView<'a> {
229 #[inline]
230 fn from(value: &'a Any) -> Self {
231 Self {
232 data: value.data,
233 _phantom: std::marker::PhantomData,
234 }
235 }
236}
237
238impl From<AnyView<'_>> for Any {
240 #[inline]
241 fn from(value: AnyView<'_>) -> Self {
242 unsafe {
243 let mut data = TVMFFIAny::new();
244 crate::check_safe_call!(TVMFFIAnyViewToOwnedAny(&value.data, &mut data)).unwrap();
245 Self { data }
246 }
247 }
248}
249
250impl<T: AnyCompatible> From<T> for Any {
251 #[inline]
252 fn from(value: T) -> Self {
253 unsafe {
254 let mut data = TVMFFIAny::new();
255 T::move_to_any(value, &mut data);
256 Self { data }
257 }
258 }
259}
260
261impl<'a, T: AnyCompatible> TryFrom<AnyView<'a>> for TryFromTemp<T> {
262 type Error = crate::error::Error;
263 #[inline]
264 fn try_from(value: AnyView<'a>) -> Result<Self, Self::Error> {
265 unsafe {
266 if T::check_any_strict(&value.data) {
267 Ok(TryFromTemp::new(T::copy_from_any_view_after_check(
268 &value.data,
269 )))
270 } else {
271 T::try_cast_from_any_view(&value.data)
272 .map_err(|_| {
273 let msg = format!(
274 "Cannot convert from type `{}` to `{}`",
275 T::get_mismatch_type_info(&value.data),
276 T::type_str()
277 );
278 crate::error::Error::new(crate::error::TYPE_ERROR, &msg, "")
279 })
280 .map(TryFromTemp::new)
281 }
282 }
283 }
284}
285
286impl<T: AnyCompatible> TryFrom<Any> for TryFromTemp<T> {
287 type Error = crate::error::Error;
288 #[inline]
289 fn try_from(value: Any) -> Result<Self, Self::Error> {
290 unsafe {
291 if T::check_any_strict(&value.data) {
292 let mut value = std::mem::ManuallyDrop::new(value);
293 Ok(TryFromTemp::new(T::move_from_any_after_check(
294 &mut value.data,
295 )))
296 } else {
297 T::try_cast_from_any_view(&value.data)
298 .map_err(|_| {
299 let msg = format!(
300 "Cannot convert from type `{}` to `{}`",
301 T::get_mismatch_type_info(&value.data),
302 T::type_str()
303 );
304 crate::error::Error::new(crate::error::TYPE_ERROR, &msg, "")
305 })
306 .map(TryFromTemp::new)
307 }
308 }
309 }
310}
311
312crate::impl_try_from_any!(
313 bool,
314 i8,
315 i16,
316 i32,
317 i64,
318 isize,
319 u8,
320 u16,
321 u32,
322 u64,
323 usize,
324 f32,
325 f64,
326 (),
327 *mut core::ffi::c_void,
328 crate::string::String,
329 crate::string::Bytes,
330 crate::object::ObjectRef,
331 tvm_ffi_sys::dlpack::DLDataType,
332 tvm_ffi_sys::dlpack::DLDevice,
333);
334
335crate::impl_try_from_any_for_parametric!(Option<T>);
336
337pub(crate) trait ArgTryFromAnyView: Sized {
341 fn try_from_any_view(value: &AnyView, arg_index: usize) -> Result<Self, Error>;
342}
343
344impl<T: AnyCompatible> ArgTryFromAnyView for T {
345 fn try_from_any_view(value: &AnyView, arg_index: usize) -> Result<Self, Error> {
346 unsafe {
347 if T::check_any_strict(&value.data) {
348 Ok(T::copy_from_any_view_after_check(&value.data))
349 } else {
350 T::try_cast_from_any_view(&value.data).map_err(|_| {
351 let msg = format!(
352 "Argument #{}: Cannot convert from type `{}` to `{}`",
353 arg_index,
354 T::get_mismatch_type_info(&value.data),
355 T::type_str()
356 );
357 crate::error::Error::new(crate::error::TYPE_ERROR, &msg, "")
358 })
359 }
360 }
361 }
362}