altv_internal_core_resource/base_objects/base_impl/
mvalue.rs1use std::ptr::NonNull;
2
3use serde::{de, ser};
4
5use super::{super::AnyBaseObject, base_ptr::BasePtr, BaseObjectContainer};
6use crate::resource::Resource;
7
8impl<T, InheritPtrs: Clone> ser::Serialize for BaseObjectContainer<T, InheritPtrs> {
10 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
11 where
12 S: ser::Serializer,
13 {
14 let raw_ptr = self.raw_base_ptr().unwrap_or(std::ptr::null_mut());
17
18 serializer.serialize_newtype_struct(mvalue::BASE_OBJECT_MVALUE, &(raw_ptr as u64))
19 }
20}
21
22struct BaseObjectVisitor;
23
24impl<'de> de::Visitor<'de> for BaseObjectVisitor {
25 type Value = AnyBaseObject;
26
27 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
28 write!(formatter, "Base Object MValue")
29 }
30
31 fn visit_u64<E>(self, base_object_ptr: u64) -> Result<Self::Value, E>
32 where
33 E: de::Error,
34 {
35 let Some(ptr) = NonNull::new(base_object_ptr as altv_sdk::BaseObjectRawMutPtr) else {
36 return Err(E::custom(
37 "Base object is invalid (it has probably already been destroyed)",
38 ));
39 };
40
41 let Some(base_object) = Resource::with_base_objects_ref(|v, _| v.get_by_ptr(ptr)) else {
42 return Err(E::custom(
43 "Base object is not found in the pool (it has probably already been destroyed)",
44 ));
45 };
46
47 Ok(base_object)
48 }
49}
50
51impl<'de> de::Deserialize<'de> for AnyBaseObject {
52 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53 where
54 D: de::Deserializer<'de>,
55 {
56 deserializer.deserialize_newtype_struct(mvalue::BASE_OBJECT_MVALUE, BaseObjectVisitor)
57 }
58}
59
60#[macro_export]
61macro_rules! __impl_mvalue_deserialize_for_base_object {
62 ($container:ty, $class_name:ident, $module_name:ident) => {
63 mod $module_name {
64 use serde::{de};
65 use std::ptr::NonNull;
66 use super::*;
67 use $crate::resource::Resource;
68
69 struct BaseObjectVisitor;
70
71 impl<'de> de::Visitor<'de> for BaseObjectVisitor {
72 type Value = $container;
73
74 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
75 write!(formatter, "{} MValue", stringify!($class_name))
76 }
77
78 fn visit_u64<E>(self, base_object_ptr: u64) -> Result<Self::Value, E>
79 where
80 E: de::Error,
81 {
82 let Some(ptr) = NonNull::new(base_object_ptr as altv_sdk::BaseObjectRawMutPtr) else {
83 return Err(E::custom(format!(
84 "{} is invalid (it has probably already been destroyed)",
85 stringify!($class_name)
86 )));
87 };
88
89 let Some(base_object) = Resource::with_base_objects_ref(|v, _| v.get_by_ptr(ptr)) else {
90 return Err(E::custom(format!(
91 "{} is not found in the pool (it has probably already been destroyed)",
92 stringify!($class_name)
93 )));
94 };
95
96 match base_object {
97 AnyBaseObject::$class_name(v) => Ok(v),
98 _ => Err(E::custom(format!(
99 "This base object is not {}",
100 stringify!($class_name)
101 ))),
102 }
103 }
104 }
105
106 impl<'de> de::Deserialize<'de> for $container {
107 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
108 where
109 D: de::Deserializer<'de>,
110 {
111 deserializer.deserialize_newtype_struct(mvalue::BASE_OBJECT_MVALUE, BaseObjectVisitor)
112 }
113 }
114 }
115 };
116}
117
118pub use __impl_mvalue_deserialize_for_base_object as impl_deserialize_for;