weakauras_codec_ace_serialize/deserialization/
mod.rs1mod reader;
5
6use crate::{error::DeserializationError, macros::check_recursion};
7use reader::StrReader;
8use weakauras_codec_lua_value::{LuaMapKey, LuaValue};
9
10pub struct Deserializer<'s> {
28 remaining_depth: usize,
29 reader: StrReader<'s>,
30}
31
32impl<'s> Deserializer<'s> {
33 #[allow(clippy::should_implement_trait)]
35 pub fn from_str(slice: &'s str) -> Self {
36 Self {
37 remaining_depth: 128,
38 reader: StrReader::new(slice),
39 }
40 }
41
42 pub fn deserialize_all(mut self) -> Result<Vec<LuaValue>, DeserializationError> {
44 self.reader.read_identifier().and_then(|v| {
45 if v == "^1" {
46 Ok(())
47 } else {
48 Err(DeserializationError::InvalidPrefix)
49 }
50 })?;
51
52 let mut result = Vec::new();
53
54 while self.reader.peek_identifier().is_ok() {
55 if let Some(v) = self.deserialize_helper()? {
56 result.push(v);
57 }
58 }
59
60 Ok(result)
61 }
62
63 pub fn deserialize_first(mut self) -> Result<Option<LuaValue>, DeserializationError> {
65 self.reader.read_identifier().and_then(|v| {
66 if v == "^1" {
67 Ok(())
68 } else {
69 Err(DeserializationError::InvalidPrefix)
70 }
71 })?;
72
73 self.deserialize_helper()
74 }
75
76 fn deserialize_helper(&mut self) -> Result<Option<LuaValue>, DeserializationError> {
77 Ok(Some(match self.reader.read_identifier()? {
78 "^^" => return Ok(None),
79 "^Z" => LuaValue::Null,
80 "^B" => LuaValue::Boolean(true),
81 "^b" => LuaValue::Boolean(false),
82 "^S" => LuaValue::String(String::from(self.reader.parse_str()?)),
83 "^N" => LuaValue::Number(
84 self.reader
85 .read_until_next()
86 .and_then(Self::deserialize_number)?,
87 ),
88 "^F" => {
89 let mantissa = self
90 .reader
91 .read_until_next()
92 .and_then(|v| v.parse::<f64>().map_err(Into::into))?;
93 let exponent = match self.reader.read_identifier()? {
94 "^f" => self
95 .reader
96 .read_until_next()
97 .and_then(|v| v.parse::<f64>().map_err(Into::into))?,
98 _ => return Err(DeserializationError::MissingExponent),
99 };
100
101 LuaValue::Number(mantissa * (2f64.powf(exponent)))
102 }
103 "^T" => {
104 let mut keys = Vec::with_capacity(16);
105 let mut values = Vec::with_capacity(16);
106 loop {
107 match self.reader.peek_identifier()? {
108 "^t" => {
109 let _ = self.reader.read_identifier();
110 break;
111 }
112 _ => {
113 check_recursion!(self, DeserializationError, {
114 let key = LuaMapKey::try_from(
115 self.deserialize_helper()?
116 .ok_or(DeserializationError::UnclosedMap)?,
117 )?;
118
119 let value = match self.reader.peek_identifier()? {
120 "^t" => {
121 return Err(DeserializationError::MapMissingValue);
122 }
123 _ => self
124 .deserialize_helper()?
125 .ok_or(DeserializationError::UnclosedMap)?,
126 };
127 keys.push(key);
128 values.push(value);
129 });
130 }
131 }
132 }
133
134 debug_assert_eq!(keys.len(), values.len());
135 let is_array = keys.iter().enumerate().all(|(i, key)| {
136 if let LuaValue::Number(key) = key.as_value() {
137 *key == (i + 1) as f64
138 } else {
139 false
140 }
141 });
142
143 if is_array {
144 LuaValue::Array(values)
145 } else {
146 LuaValue::Map(keys.into_iter().zip(values).collect())
147 }
148 }
149 _ => return Err(DeserializationError::InvalidIdentifier),
150 }))
151 }
152
153 fn deserialize_number(data: &str) -> Result<f64, DeserializationError> {
154 match data {
155 "1.#INF" | "inf" => Ok(f64::INFINITY),
156 "-1.#INF" | "-inf" => Ok(f64::NEG_INFINITY),
157 v => v.parse().map_err(Into::into),
158 }
159 }
160}