serde_hkx/xml/de/
map.rs
1use crate::{
4 tri,
5 xml::de::parser::{delimited_multispace0_comment, delimited_with_multispace0},
6};
7
8use super::{
9 XmlDeserializer,
10 parser::tag::{end_tag, field_start_close_tag, field_start_open_tag},
11};
12use crate::errors::de::{Error, Result};
13use havok_serde::de::{DeserializeSeed, MapAccess};
14use havok_types::Pointer;
15use winnow::{Parser as _, combinator::alt, token::take_until};
16
17#[derive(Debug)]
30pub struct MapDeserializer<'a, 'de: 'a> {
31 de: &'a mut XmlDeserializer<'de>,
33 ptr_name: Option<Pointer>,
34 class_name: &'static str,
35}
36
37impl<'a, 'de> MapDeserializer<'a, 'de> {
38 #[inline]
40 pub const fn new(
41 de: &'a mut XmlDeserializer<'de>,
42 ptr_name: Option<Pointer>,
43 class_name: &'static str,
44 ) -> Self {
45 Self {
46 de,
47 ptr_name,
48 class_name,
49 }
50 }
51}
52
53impl<'de> MapAccess<'de> for MapDeserializer<'_, 'de> {
54 type Error = Error;
55
56 #[inline]
57 fn class_ptr(&mut self) -> Option<Pointer> {
58 self.ptr_name.take()
59 }
60
61 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
63 where
64 K: DeserializeSeed<'de>,
65 {
66 if self.de.parse_peek(end_tag("hkobject")).is_ok() {
68 return Ok(None);
69 }
70 if self.de.input.is_empty() {
72 return Err(Error::Eof);
73 }
74
75 tri!(self.de.parse_next(field_start_open_tag(self.class_name))); seed.deserialize(&mut *self.de).map(Some) }
78
79 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
81 where
82 V: DeserializeSeed<'de>,
83 {
84 let (_len, is_self_closing) = tri!(self.de.parse_next(field_start_close_tag)); #[cfg(feature = "tracing")]
89 if let Some(numelements) = _len {
90 tracing::debug!(numelements);
91 }
92
93 if is_self_closing {
94 const EMPTY_INPUT: &str = "";
97 let original_input = self.de.input;
98 self.de.input = EMPTY_INPUT;
99 let result = seed.deserialize(&mut *self.de);
100 self.de.input = original_input;
101 result
102 } else {
103 let value = tri!(seed.deserialize(&mut *self.de));
104 tri!(self.de.parse_next(end_tag("hkparam")));
105 Ok(value)
106 }
107 }
108
109 fn skip_value_seed(&mut self) -> std::result::Result<(), Self::Error> {
111 let ((_num, _is_self_closing), _value) = tri!(
112 self.de.parse_next(alt((
113 winnow::seq! {
114 field_start_close_tag, take_until(0.., "<"), _: end_tag("hkparam") },
118 winnow::seq! { _: delimited_with_multispace0("/"),
120 _: delimited_multispace0_comment(">")
121 }
122 .map(|_| ((None, true), "")),
123 )))
124 );
125 #[cfg(feature = "tracing")]
126 {
127 let numelements = _num
128 .map(|n| format!("numelements=\"{n}\""))
129 .unwrap_or_default();
130 tracing::debug!("`Skip `{numelements}>{_value}</hkparam>`.");
131 }
132 Ok(())
133 }
134
135 #[cold]
136 fn parent_value_seed<V>(&mut self, _seed: V) -> Result<V::Value, Self::Error>
137 where
138 V: DeserializeSeed<'de>,
139 {
140 unreachable!(
141 "Using the wrong API: This method is not used in `havok_classes` in XML because it is for bytes."
142 )
143 }
144}