1use crate::access::{AttributesWrapperAccess, CommaSeparated, EmptyMapAccess, EnumAccess};
2use crate::lexer::YsonIterator;
3use crate::node::{Token, YsonNode, YsonValue};
4use crate::{access::FlatStructAccess, error::YsonError};
5use serde::Deserialize;
6use serde::de::{self, MapAccess, SeqAccess, Visitor};
7use std::borrow::Cow;
8use std::collections::BTreeMap;
9
10pub struct Deserializer<'de> {
12 pub(crate) lexer: YsonIterator<'de>,
13 pub(crate) is_reading_attributes: bool,
14 depth: usize,
15 max_depth: usize,
16}
17
18impl<'de> Deserializer<'de> {
19 #[must_use]
40 pub fn from_bytes(input: &'de [u8], is_binary: bool) -> Self {
41 Deserializer {
42 lexer: YsonIterator::new(input, is_binary),
43 is_reading_attributes: false,
44 depth: 0,
45 max_depth: 128,
46 }
47 }
48
49 pub(crate) fn enter_recursion(&mut self) -> Result<(), YsonError> {
50 self.depth += 1;
51 if self.depth > self.max_depth {
52 return Err(YsonError::Custom("Recursion limit exceeded".into()));
53 }
54 Ok(())
55 }
56
57 pub(crate) fn leave_recursion(&mut self) {
58 self.depth -= 1;
59 }
60
61 fn skip_attributes(&mut self) -> Result<(), YsonError> {
62 if self.lexer.peek_byte()? == b'<' {
63 self.enter_recursion()?;
64 self.lexer.next_token()?;
65 let mut attr_depth = 1;
66 while attr_depth > 0 {
67 match self.lexer.next_token()? {
68 Token::BeginAttributes => attr_depth += 1,
69 Token::EndAttributes => attr_depth -= 1,
70 _ => {}
71 }
72 if attr_depth > self.max_depth {
73 return Err(YsonError::Custom("Attributes nesting too deep".into()));
74 }
75 }
76 self.leave_recursion();
77 }
78 Ok(())
79 }
80}
81
82macro_rules! delegate_skip_attributes {
83 ( $($method:ident),* $(,)? ) => {
84 $(
85 fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
86 where
87 V: Visitor<'de>,
88 {
89 if !self.is_reading_attributes {
90 self.skip_attributes()?;
91 }
92 self.deserialize_any(visitor)
93 }
94 )*
95 };
96}
97
98impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
99 type Error = YsonError;
100
101 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
102 where
103 V: Visitor<'de>,
104 {
105 let was_reading_attributes = self.is_reading_attributes;
106 self.is_reading_attributes = false;
107
108 if was_reading_attributes {
109 if self.lexer.peek_byte()? != b'<' {
110 return visitor.visit_map(EmptyMapAccess);
111 }
112 self.lexer.next_token()?;
113 return visitor.visit_map(CommaSeparated::new(self, b'>')?);
114 }
115
116 if self.lexer.peek_byte()? == b'<' {
117 return visitor.visit_map(FlatStructAccess::new(self)?);
118 }
119
120 match self.lexer.next_token()? {
121 Token::Entity => visitor.visit_unit(),
122 Token::Boolean(b) => visitor.visit_bool(b),
123 Token::Int64(i) => visitor.visit_i64(i),
124 Token::Uint64(u) => visitor.visit_u64(u),
125 Token::Double(d) => visitor.visit_f64(d),
126 Token::String(s) => match s {
127 Cow::Borrowed(b) => {
128 if let Ok(utf8) = std::str::from_utf8(b) {
129 visitor.visit_borrowed_str(utf8)
130 } else {
131 visitor.visit_borrowed_bytes(b)
132 }
133 }
134 Cow::Owned(vec) => match String::from_utf8(vec) {
135 Ok(utf8) => visitor.visit_string(utf8),
136 Err(e) => visitor.visit_byte_buf(e.into_bytes()),
137 },
138 },
139 Token::BeginList => visitor.visit_seq(CommaSeparated::new(self, b']')?),
140 Token::BeginMap => visitor.visit_map(CommaSeparated::new(self, b'}')?),
141 Token::BeginAttributes => visitor.visit_map(CommaSeparated::new(self, b'>')?),
142 t => Err(YsonError::Custom(format!("Unexpected token: {t:?}"))),
143 }
144 }
145
146 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
147 where
148 V: Visitor<'de>,
149 {
150 let was_reading_attributes = self.is_reading_attributes;
151 self.is_reading_attributes = false;
152
153 if was_reading_attributes {
154 if self.lexer.peek_byte()? == b'<' {
155 self.is_reading_attributes = true;
156 let res = visitor.visit_some(&mut *self);
157 self.is_reading_attributes = false;
158 res
159 } else {
160 visitor.visit_none()
161 }
162 } else {
163 self.skip_attributes()?;
164 if self.lexer.peek_byte()? == b'#' {
165 self.lexer.next_token()?;
166 visitor.visit_none()
167 } else {
168 visitor.visit_some(self)
169 }
170 }
171 }
172
173 fn deserialize_struct<V>(
174 self,
175 name: &'static str,
176 fields: &'static [&'static str],
177 visitor: V,
178 ) -> Result<V::Value, Self::Error>
179 where
180 V: Visitor<'de>,
181 {
182 if name == "$__yson_attributes" {
183 return visitor.visit_seq(AttributesWrapperAccess::new(self)?);
184 }
185 if fields.iter().any(|f| f.starts_with('@')) {
186 return visitor.visit_map(FlatStructAccess::new(self)?);
187 }
188
189 if !self.is_reading_attributes {
190 self.skip_attributes()?;
191 }
192 self.deserialize_any(visitor)
193 }
194
195 fn deserialize_enum<V>(
196 self,
197 _name: &'static str,
198 _variants: &'static [&'static str],
199 visitor: V,
200 ) -> Result<V::Value, Self::Error>
201 where
202 V: Visitor<'de>,
203 {
204 if !self.is_reading_attributes {
205 self.skip_attributes()?;
206 }
207
208 let peeked = self.lexer.peek_byte()?;
209 if peeked == b'{' {
210 self.lexer.next_token()?;
211 let val = visitor.visit_enum(EnumAccess::new(self, true))?;
212
213 loop {
214 match self.lexer.peek_byte() {
215 Ok(b';' | b'}') => break,
216 Ok(_) => {
217 self.lexer.next_token()?;
218 }
219 Err(_) => break,
220 }
221 }
222
223 if let Ok(b';') = self.lexer.peek_byte() {
224 self.lexer.next_token()?;
225 }
226
227 match self.lexer.next_token()? {
228 Token::EndMap => Ok(val),
229 t => Err(YsonError::Custom(format!(
230 "Expected '}}' after variant, got {t:?}"
231 ))),
232 }
233 } else {
234 visitor.visit_enum(EnumAccess::new(self, false))
235 }
236 }
237
238 delegate_skip_attributes! {
239 deserialize_bool, deserialize_i8, deserialize_i16, deserialize_i32,
240 deserialize_i64, deserialize_i128, deserialize_u8, deserialize_u16,
241 deserialize_u32, deserialize_u64, deserialize_u128, deserialize_f32,
242 deserialize_f64, deserialize_char, deserialize_str, deserialize_string,
243 deserialize_bytes, deserialize_byte_buf, deserialize_unit,
244 deserialize_seq, deserialize_map, deserialize_identifier,
245 deserialize_ignored_any
246 }
247
248 fn deserialize_unit_struct<V>(
249 self,
250 _name: &'static str,
251 visitor: V,
252 ) -> Result<V::Value, Self::Error>
253 where
254 V: Visitor<'de>,
255 {
256 if !self.is_reading_attributes {
257 self.skip_attributes()?;
258 }
259 self.deserialize_any(visitor)
260 }
261
262 fn deserialize_newtype_struct<V>(
263 self,
264 _name: &'static str,
265 visitor: V,
266 ) -> Result<V::Value, Self::Error>
267 where
268 V: Visitor<'de>,
269 {
270 if !self.is_reading_attributes {
271 self.skip_attributes()?;
272 }
273 self.deserialize_any(visitor)
274 }
275
276 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
277 where
278 V: Visitor<'de>,
279 {
280 if !self.is_reading_attributes {
281 self.skip_attributes()?;
282 }
283 self.deserialize_any(visitor)
284 }
285
286 fn deserialize_tuple_struct<V>(
287 self,
288 _name: &'static str,
289 _len: usize,
290 visitor: V,
291 ) -> Result<V::Value, Self::Error>
292 where
293 V: Visitor<'de>,
294 {
295 if !self.is_reading_attributes {
296 self.skip_attributes()?;
297 }
298 self.deserialize_any(visitor)
299 }
300}
301
302pub struct StreamDeserializer<'de, T> {
323 de: Deserializer<'de>,
324 first: bool,
325 _marker: std::marker::PhantomData<T>,
326}
327
328impl<'de, T> StreamDeserializer<'de, T>
329where
330 T: de::Deserialize<'de>,
331{
332 #[must_use]
339 pub fn new(input: &'de [u8], is_binary: bool) -> Self {
340 Self {
341 de: Deserializer::from_bytes(input, is_binary),
342 first: true,
343 _marker: std::marker::PhantomData,
344 }
345 }
346
347 pub fn next_item(&mut self) -> Result<Option<T>, YsonError> {
362 let peek_res = self.de.lexer.peek_byte();
363
364 if matches!(peek_res, Err(YsonError::Eof)) {
365 return Ok(None);
366 }
367
368 let next_byte = peek_res?;
369
370 if self.first {
371 self.first = false;
372 } else if next_byte == b';' {
373 self.de.lexer.next_token()?;
374 if matches!(self.de.lexer.peek_byte(), Err(YsonError::Eof)) {
375 return Ok(None);
376 }
377 }
378
379 let item = T::deserialize(&mut self.de)?;
380 Ok(Some(item))
381 }
382}
383
384struct MapKey(Vec<u8>);
391
392impl<'de> Deserialize<'de> for MapKey {
393 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
394 where
395 D: de::Deserializer<'de>,
396 {
397 struct MapKeyVisitor;
398
399 impl Visitor<'_> for MapKeyVisitor {
400 type Value = MapKey;
401
402 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
403 formatter.write_str("a YSON map key (byte string)")
404 }
405
406 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
407 Ok(MapKey(v.as_bytes().to_vec()))
408 }
409
410 fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
411 Ok(MapKey(v.into_bytes()))
412 }
413
414 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
415 Ok(MapKey(v.to_vec()))
416 }
417
418 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
419 Ok(MapKey(v))
420 }
421 }
422
423 deserializer.deserialize_any(MapKeyVisitor)
424 }
425}
426
427macro_rules! impl_visit_primitives {
428 ( $( $method:ident ( $v_type:ty ) => $node_variant:ident ),* ) => {
429 $(
430 fn $method<E>(self, v: $v_type) -> Result<Self::Value, E> {
431 Ok(YsonValue {
432 attributes: None,
433 node: YsonNode::$node_variant(v),
434 })
435 }
436 )*
437 };
438}
439
440impl<'de> Deserialize<'de> for YsonValue {
441 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
442 where
443 D: de::Deserializer<'de>,
444 {
445 struct YsonValueVisitor;
446
447 impl<'de> Visitor<'de> for YsonValueVisitor {
448 type Value = YsonValue;
449
450 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
451 formatter.write_str("any YSON value")
452 }
453
454 impl_visit_primitives! {
455 visit_bool(bool) => Boolean,
456 visit_i64(i64) => Int64,
457 visit_u64(u64) => Uint64,
458 visit_f64(f64) => Double
459 }
460
461 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
462 Ok(YsonValue {
463 attributes: None,
464 node: YsonNode::String(v.as_bytes().to_vec()),
465 })
466 }
467
468 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
469 Ok(YsonValue {
470 attributes: None,
471 node: YsonNode::String(v.to_vec()),
472 })
473 }
474
475 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
476 Ok(YsonValue {
477 attributes: None,
478 node: YsonNode::String(v),
479 })
480 }
481
482 fn visit_unit<E>(self) -> Result<Self::Value, E> {
483 Ok(YsonValue {
484 attributes: None,
485 node: YsonNode::Entity,
486 })
487 }
488
489 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
490 where
491 A: SeqAccess<'de>,
492 {
493 let mut vec = Vec::new();
494 while let Some(elem) = seq.next_element()? {
495 vec.push(elem);
496 }
497 Ok(YsonValue {
498 attributes: None,
499 node: YsonNode::List(vec),
500 })
501 }
502
503 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
504 where
505 M: MapAccess<'de>,
506 {
507 let mut attributes = BTreeMap::new();
508 let mut plain_map = BTreeMap::new();
509 let mut body_node = None;
510 let mut is_attributed = false;
511
512 while let Some(MapKey(key)) = map.next_key::<MapKey>()? {
513 if let Some(attr_name) = key.strip_prefix(b"@") {
514 is_attributed = true;
515 attributes.insert(attr_name.to_vec(), map.next_value()?);
516 } else if key == b"$value" {
517 is_attributed = true;
518 let val: YsonValue = map.next_value()?;
519 body_node = Some(val.node);
520 if let Some(inner_attrs) = val.attributes {
521 attributes.extend(inner_attrs);
522 }
523 } else {
524 plain_map.insert(key, map.next_value()?);
525 }
526 }
527
528 if is_attributed {
529 Ok(YsonValue {
530 attributes: if attributes.is_empty() {
531 None
532 } else {
533 Some(attributes)
534 },
535 node: body_node.unwrap_or(YsonNode::Entity),
536 })
537 } else {
538 Ok(YsonValue {
539 attributes: None,
540 node: YsonNode::Map(plain_map),
541 })
542 }
543 }
544 }
545
546 deserializer.deserialize_any(YsonValueVisitor)
547 }
548}