altv_internal_mvalue 16.4.3

An internal crate for alt:V module. Not intended for direct use.
Documentation
use crate::{ConstMValue, Deserializer, Error, Result};

use serde::{de, forward_to_deserialize_any, Deserialize};

struct ConstMValueSliceDeserializer<'de> {
  input: &'de [ConstMValue],
}

impl<'de> ConstMValueSliceDeserializer<'de> {
  pub fn from_mvalue_slice(input: &'de [ConstMValue]) -> Self {
    ConstMValueSliceDeserializer { input }
  }
}

pub fn from_mvalue_slice<'de, T>(m: &'de [ConstMValue]) -> Result<T>
where
  T: Deserialize<'de>,
{
  let deserializer = ConstMValueSliceDeserializer::from_mvalue_slice(m);
  let t = T::deserialize(deserializer)?;
  Ok(t)
}

impl<'de> de::Deserializer<'de> for ConstMValueSliceDeserializer<'de> {
  type Error = Error;

  fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
  where
    V: de::Visitor<'de>,
  {
    visitor.visit_seq(Seq::new(self.input))
  }

  /////////////////////////////////////////////////////////////////////////////

  fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
  where
    V: de::Visitor<'de>,
  {
    Err(Error::ConstMValueSliceCanOnlyBeDeserializedAsTuple)
  }

  forward_to_deserialize_any! {
      bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string
      bytes byte_buf option unit unit_struct newtype_struct seq
      tuple_struct map struct enum identifier ignored_any
  }
}

struct Seq<'de> {
  slice: &'de [ConstMValue],
  current_idx: usize,
}

impl<'de> Seq<'de> {
  fn new(slice: &'de [ConstMValue]) -> Self {
    Self {
      slice,
      current_idx: 0,
    }
  }

  fn next(&mut self) -> Option<ConstMValue> {
    if self.current_idx == self.slice.len() {
      return None;
    }
    let value = self.slice.get(self.current_idx);
    self.current_idx += 1;
    value.cloned()
  }
}

impl<'de> de::SeqAccess<'de> for Seq<'de> {
  type Error = Error;

  fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
  where
    T: de::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)
  }
}

pub trait DeserializeMValueArgs {
  fn deserialize<'de, V: Deserialize<'de>>(&'de self) -> Result<V>;
}

impl DeserializeMValueArgs for Vec<ConstMValue> {
  fn deserialize<'de, V: Deserialize<'de>>(&'de self) -> Result<V> {
    from_mvalue_slice(self)
  }
}