serde_hkx/bytes/de/
map.rs

1//! Deserializing each field element in an `Struct`
2use super::BytesDeserializer;
3use crate::errors::de::Error;
4use havok_serde::de::{DeserializeSeed, MapAccess};
5use havok_types::Pointer;
6
7/// A structure for deserializing each element in an `Struct`.
8#[derive(Debug)]
9pub struct MapDeserializer<'a, 'de: 'a> {
10    /// Deserializer
11    de: &'a mut BytesDeserializer<'de>,
12
13    #[allow(unused)]
14    /// Field index currently being processed
15    field_index: usize,
16    #[allow(unused)]
17    /// Field length currently being processed
18    fields: &'static [&'static str],
19}
20
21impl<'a, 'de> MapDeserializer<'a, 'de> {
22    /// Create a new map deserializer
23    #[inline]
24    pub const fn new(de: &'a mut BytesDeserializer<'de>, fields: &'static [&'static str]) -> Self {
25        Self {
26            de,
27            field_index: 0,
28            fields,
29        }
30    }
31}
32
33impl<'de> MapAccess<'de> for MapDeserializer<'_, 'de> {
34    type Error = Error;
35
36    #[inline]
37    fn class_ptr(&mut self) -> Option<Pointer> {
38        self.de.takable_class_index.take()
39    }
40
41    fn pad(&mut self, x86_pad: usize, x64_pad: usize) -> Result<(), Self::Error> {
42        let pad = if self.de.is_x86 { x86_pad } else { x64_pad };
43
44        if pad <= self.de.input.len() {
45            self.de.current_position += pad;
46
47            #[cfg(feature = "tracing")]
48            tracing::trace!(
49                "padding: {pad} -> current position: {:#x}",
50                self.de.current_position
51            );
52            Ok(())
53        } else {
54            Err(Error::Eof)
55        }
56    }
57
58    // NOTE: This method is never used with bytes because the number of times is controlled by the for loop.
59    #[cold]
60    fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>, Self::Error>
61    where
62        K: DeserializeSeed<'de>,
63    {
64        unimplemented!("Use only `next_value` for Deserialize Bytes.")
65    }
66
67    // Parse field
68    #[cfg_attr(not(feature = "tracing"), inline)]
69    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
70    where
71        V: DeserializeSeed<'de>,
72    {
73        #[cfg(feature = "tracing")]
74        {
75            if self.field_index == 0 {
76                tracing::trace!("fields: {:?}", self.fields);
77            };
78
79            if let Some(field_name) = self.fields.get(self.field_index) {
80                tracing::trace!(
81                    "deserialize {}th field({:#x}): {field_name}",
82                    self.field_index,
83                    self.de.current_position
84                );
85            } else {
86                tracing::warn!(
87                    "invalid field index: {} of {}",
88                    self.field_index,
89                    self.fields.len()
90                );
91            };
92            self.field_index += 1;
93        }
94
95        seed.deserialize(&mut *self.de)
96    }
97
98    /// This method is now only used for XML.
99    #[inline]
100    fn skip_value_seed(&mut self) -> std::result::Result<(), Self::Error> {
101        Ok(())
102    }
103
104    // Do the same thing as `next_value`, but separate them so that the current field name
105    // to be deserialized is logged correctly.
106    //
107    // This is the method separation for this purpose. (For now).
108    #[inline]
109    fn parent_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
110    where
111        V: DeserializeSeed<'de>,
112    {
113        seed.deserialize(&mut *self.de)
114    }
115}