use altv_sdk::{ffi as sdk, MValueType};
use autocxx::{cxx::CxxVector, prelude::*};
use serde::de::{
self, DeserializeOwned, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess,
Visitor, Deserializer as _,
};
use crate::{
bytes_num,
de_any_mvalue_variant::{AnyMValueVariantDeserializer, ANY_MVALUE_ENUM},
de_dict_key::DictKeyDeserializer,
de_enum_variant::EnumVariantDeserializer,
helpers::{self, deserialize_simple, deserialize_simple_unchecked, sdk_type_to_rust},
ser_rgba::RGBA_MVALUE,
ser_vector2::VECTOR2_MVALUE,
ser_vector3::VECTOR3_MVALUE,
wrappers::ConstMValue,
Error, Result, BASE_OBJECT_MVALUE,
};
pub struct Deserializer {
input: ConstMValue,
}
impl Deserializer {
pub fn from_mvalue(input: ConstMValue) -> Self {
Deserializer { input }
}
fn mvalue_type(&self) -> Result<MValueType> {
self.input.sdk_mvalue_type()
}
fn assert_mvalue_type(&self, received: MValueType, expected: MValueType) -> Result<()> {
if received != expected {
let mvalue_type_rust = helpers::sdk_type_to_rust(received);
let expected_rust = helpers::sdk_type_to_rust(expected);
return Err(Error::Message(format!(
"Expected: {expected_rust}, received: {mvalue_type_rust}"
)));
}
Ok(())
}
fn deserialize_byte_buf_unchecked<'de, V>(&self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let mvalue = self.input.get();
let size = unsafe { sdk::read_mvalue_byte_array_size(mvalue) };
let mut buffer = Vec::<u8>::with_capacity(size);
unsafe {
sdk::read_mvalue_byte_array(mvalue, buffer.as_mut_ptr());
buffer.set_len(size);
}
visitor.visit_byte_buf(buffer)
}
fn deserialize_seq_unchecked<'de, V>(&self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_seq(Seq::new(unsafe { sdk::read_mvalue_list(self.input.get()) }))
}
fn deserialize_map_unchecked<'de, V>(&self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
visitor.visit_map(Map::new(unsafe { sdk::read_mvalue_dict(self.input.get()) }))
}
}
pub fn from_mvalue<T>(m: &ConstMValue) -> Result<T>
where
T: DeserializeOwned,
{
let mut deserializer = Deserializer::from_mvalue(m.clone());
let t = T::deserialize(&mut deserializer)?;
Ok(t)
}
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match self.mvalue_type()? {
MValueType::Double => {
deserialize_simple_unchecked!(self, visitor, @sdk Double: @rust f64)
}
MValueType::Int => deserialize_simple_unchecked!(self, visitor, @sdk Int: @rust i64),
MValueType::Uint => deserialize_simple_unchecked!(self, visitor, @sdk Uint: @rust u64),
MValueType::Bool => deserialize_simple_unchecked!(self, visitor, @sdk Bool: @rust bool),
MValueType::Nil | MValueType::None => visitor.visit_none(),
MValueType::ByteArray => self.deserialize_byte_buf_unchecked(visitor),
MValueType::String => {
deserialize_simple_unchecked!(self, visitor, @sdk String: @rust String, to_string)
}
MValueType::List => self.deserialize_seq_unchecked(visitor),
MValueType::Dict => self.deserialize_map_unchecked(visitor),
MValueType::BaseObject => self.deserialize_newtype_struct(BASE_OBJECT_MVALUE, visitor),
MValueType::Rgba => self.deserialize_newtype_struct(RGBA_MVALUE, visitor),
MValueType::Vector2 => self.deserialize_newtype_struct(VECTOR2_MVALUE, visitor),
MValueType::Vector3 => self.deserialize_newtype_struct(VECTOR3_MVALUE, visitor),
MValueType::Function => panic!(
"Cannot deserialize {}",
sdk_type_to_rust(MValueType::Function)
),
}
}
fn deserialize_ignored_any<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.assert_mvalue_type(self.mvalue_type()?, MValueType::Dict)?;
self.deserialize_map_unchecked(visitor)
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_map(visitor)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.assert_mvalue_type(self.mvalue_type()?, MValueType::List)?;
self.deserialize_seq_unchecked(visitor)
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_tuple(len, visitor)
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match self.mvalue_type()? {
MValueType::None | MValueType::Nil => visitor.visit_unit(),
received => {
let mvalue_type_rust = helpers::sdk_type_to_rust(received);
Err(Error::Message(format!(
"Expected: (), received: {mvalue_type_rust}"
)))
}
}
}
fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
deserialize_simple!(self, visitor, @sdk String: @rust String, to_string)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
deserialize_simple!(self, visitor, @sdk Bool: @rust bool)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
deserialize_simple!(self, visitor, @sdk Int: @rust i64)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_u64(visitor)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
deserialize_simple!(self, visitor, @sdk Uint: @rust u64)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.deserialize_f64(visitor)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
deserialize_simple!(self, visitor, @sdk Double: @rust f64)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match self.mvalue_type()? {
MValueType::None | MValueType::Nil => visitor.visit_none(),
_ => visitor.visit_some(self),
}
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
let mvalue_type = self.mvalue_type()?;
let mvalue = self.input.get();
match name {
RGBA_MVALUE => {
self.assert_mvalue_type(mvalue_type, MValueType::Rgba)?;
let ptr = unsafe { sdk::read_mvalue_rgba(mvalue) }.within_unique_ptr();
let (mut r, mut g, mut b, mut a) = Default::default();
unsafe {
sdk::read_rgba(ptr.as_ref().unwrap(), &mut r, &mut g, &mut b, &mut a);
}
let buf = bytes_num::to_byte_buf([r, g, b, a]);
visitor.visit_byte_buf(buf)
}
VECTOR3_MVALUE => {
self.assert_mvalue_type(mvalue_type, MValueType::Vector3)?;
let ptr = unsafe { sdk::read_mvalue_vector3(mvalue) }.within_unique_ptr();
let (mut x, mut y, mut z) = Default::default();
unsafe {
sdk::read_vector3(
ptr.as_ref().unwrap(),
&mut x as *mut f32,
&mut y as *mut f32,
&mut z as *mut f32,
);
}
let buf = bytes_num::to_byte_buf([x, y, z]);
visitor.visit_byte_buf(buf)
}
VECTOR2_MVALUE => {
self.assert_mvalue_type(mvalue_type, MValueType::Vector2)?;
let ptr = unsafe { sdk::read_mvalue_vector2(mvalue) }.within_unique_ptr();
let (mut x, mut y) = Default::default();
unsafe {
sdk::read_vector2(
ptr.as_ref().unwrap(),
&mut x as *mut f32,
&mut y as *mut f32,
);
}
let buf = bytes_num::to_byte_buf([x, y]);
visitor.visit_byte_buf(buf)
}
BASE_OBJECT_MVALUE => {
self.assert_mvalue_type(mvalue_type, MValueType::BaseObject)?;
let raw_ptr = unsafe { sdk::read_mvalue_base_object(mvalue) };
visitor.visit_u64(raw_ptr as u64)
}
_ => {
logger::debug!("passing newtype_struct: {name} to visit_newtype_struct");
visitor.visit_newtype_struct(self)
}
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.assert_mvalue_type(self.mvalue_type()?, MValueType::ByteArray)?;
self.deserialize_byte_buf_unchecked(visitor)
}
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
Err(Error::BytesDeserializationIsNotImplementedYet)
}
fn deserialize_enum<V>(
self,
name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
if name == ANY_MVALUE_ENUM {
visitor.visit_enum(Enum::new(self.input.clone(), AnyMValueEnum))
} else {
match self.mvalue_type()? {
MValueType::Int => {
let variant_index: i32 = from_mvalue(&self.input).expect("already checked to be i32");
visitor.visit_enum(Enum::new(
self.input.clone(),
NotAnyMValueEnum {
variant_index: variant_index.try_into().unwrap(),
variant_value: None,
},
))
}
MValueType::List => {
let error = || Error::EnumDeserializationExpectsListWithTwoElements;
let mut entry = Seq::new(unsafe { sdk::read_mvalue_list(self.input.get()) });
let variant_index = entry.next().ok_or_else(error)?;
let variant_index: i32 = from_mvalue(&variant_index).map_err(|_| error())?;
let variant_value = entry.next().ok_or_else(error)?;
visitor.visit_enum(Enum::new(
self.input.clone(),
NotAnyMValueEnum {
variant_index: variant_index.try_into().unwrap(),
variant_value: Some(variant_value),
},
))
}
mvalue_type => Err(Error::EnumDeserializationExpectsListOrInt {
but_received: mvalue_type,
}),
}
}
}
}
struct Seq {
mvalue_list: UniquePtr<CxxVector<sdk::ConstMValueWrapper>>,
current_idx: usize,
}
impl Seq {
fn new(mvalue_list: UniquePtr<CxxVector<sdk::ConstMValueWrapper>>) -> Self {
Self {
mvalue_list,
current_idx: 0,
}
}
fn next(&mut self) -> Option<ConstMValue> {
if self.current_idx == self.mvalue_list.len() {
return None;
}
let value = self.mvalue_list.get(self.current_idx);
let value =
value.map(|v| ConstMValue::new(unsafe { sdk::copy_const_mvalue(v) }.within_unique_ptr()));
self.current_idx += 1;
value
}
}
impl<'de> SeqAccess<'de> for Seq {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
let next = self.next();
let Some(mvalue) = next else {
return Ok(None);
};
let mut deserializer = Deserializer::from_mvalue(mvalue);
seed.deserialize(&mut deserializer).map(Some)
}
}
struct Map {
mvalue_dict: UniquePtr<CxxVector<sdk::MValueDictPairWrapper>>,
current_idx: usize,
current_pair: Option<UniquePtr<sdk::MValueDictPairWrapper>>,
}
impl Map {
fn new(mvalue_dict: UniquePtr<CxxVector<sdk::MValueDictPairWrapper>>) -> Self {
Self {
mvalue_dict,
current_idx: 0,
current_pair: None,
}
}
fn next(&mut self) -> &Option<UniquePtr<sdk::MValueDictPairWrapper>> {
if self.current_idx == self.mvalue_dict.len() {
return &None;
}
let value = self.mvalue_dict.get(self.current_idx);
self.current_idx += 1;
self.current_pair = value.map(|v| unsafe { sdk::copy_mvalue_dict_pair(v) }.within_unique_ptr());
&self.current_pair
}
fn current_pair_value(&self) -> ConstMValue {
let pair = self.current_pair.as_ref().unwrap();
ConstMValue::new(
unsafe { sdk::read_mvalue_dict_pair_value(pair.as_ref().unwrap()) }.within_unique_ptr(),
)
}
}
impl<'de> MapAccess<'de> for Map {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: DeserializeSeed<'de>,
{
let next = self.next();
let Some(pair) = next else {
return Ok(None);
};
let key = unsafe { sdk::read_mvalue_dict_pair_key(pair.as_ref().unwrap()) };
let key = seed.deserialize(DictKeyDeserializer::from_cpp_string(key))?;
Ok(Some(key))
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: DeserializeSeed<'de>,
{
let value = self.current_pair_value();
let mut deserializer = Deserializer::from_mvalue(value);
let value = seed.deserialize(&mut deserializer)?;
Ok(value)
}
}
struct Enum<Data> {
mvalue: ConstMValue,
data: Data,
}
impl<Data> Enum<Data> {
fn new(mvalue: ConstMValue, data: Data) -> Self {
Self { mvalue, data }
}
}
struct AnyMValueEnum;
impl<'de> EnumAccess<'de> for Enum<AnyMValueEnum> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: DeserializeSeed<'de>,
{
let deserializer = AnyMValueVariantDeserializer::from_cpp(self.mvalue.clone());
let value = seed.deserialize(deserializer)?;
Ok((value, self))
}
}
struct NotAnyMValueEnum {
variant_index: u32,
variant_value: Option<ConstMValue>,
}
impl Enum<NotAnyMValueEnum> {
fn get_variant_value(self) -> Result<ConstMValue> {
match self.data.variant_value {
Some(mvalue) => Ok(mvalue),
None => {
Err(Error::EnumDeserializationExpectsList {
but_received: MValueType::Int,
})
}
}
}
}
impl<'de> EnumAccess<'de> for Enum<NotAnyMValueEnum> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: DeserializeSeed<'de>,
{
let deserializer = EnumVariantDeserializer::from_cpp(self.data.variant_index);
let value = seed.deserialize(deserializer)?;
Ok((value, self))
}
}
impl<'de> VariantAccess<'de> for Enum<AnyMValueEnum> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where
T: de::DeserializeSeed<'de>,
{
let mut deserializer = Deserializer::from_mvalue(self.mvalue);
let value = seed.deserialize(&mut deserializer)?;
Ok(value)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let mut deserializer = Deserializer::from_mvalue(self.mvalue);
deserializer.deserialize_seq(visitor)
}
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let mut deserializer = Deserializer::from_mvalue(self.mvalue);
deserializer.deserialize_struct("", fields, visitor)
}
}
impl<'de> VariantAccess<'de> for Enum<NotAnyMValueEnum> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where
T: de::DeserializeSeed<'de>,
{
let mut deserializer = Deserializer::from_mvalue(self.get_variant_value()?);
let value = seed.deserialize(&mut deserializer)?;
Ok(value)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let mut deserializer = Deserializer::from_mvalue(self.get_variant_value()?);
deserializer.deserialize_seq(visitor)
}
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let mut deserializer = Deserializer::from_mvalue(self.get_variant_value()?);
deserializer.deserialize_struct("", fields, visitor)
}
}