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 pub(crate) container_ended: bool,
20 depth: usize,
21 max_depth: usize,
22}
23
24impl<'de> Deserializer<'de> {
25 #[must_use]
46 pub fn from_bytes(input: &'de [u8], is_binary: bool) -> Self {
47 Deserializer {
48 lexer: YsonIterator::new(input, is_binary),
49 is_reading_attributes: false,
50 container_ended: false,
51 depth: 0,
52 max_depth: 128,
53 }
54 }
55
56 fn end_container(&mut self, end_byte: u8) -> Result<(), YsonError> {
73 if self.container_ended {
74 return Ok(());
75 }
76
77 if self.lexer.peek_byte()? == b';' {
80 self.lexer.next_token()?;
81 }
82
83 let byte = self.lexer.peek_byte()?;
84 if byte != end_byte {
85 return Err(YsonError::Custom(format!(
86 "expected {:?} to close the value, found byte {byte:#04x} at offset {}",
87 end_byte as char,
88 self.lexer.pos()
89 )));
90 }
91 self.lexer.next_token()?;
92 Ok(())
93 }
94
95 pub fn end(&mut self) -> Result<(), YsonError> {
105 match self.lexer.peek_byte() {
106 Err(YsonError::Eof) => Ok(()),
107 Ok(byte) => Err(YsonError::Custom(format!(
108 "trailing data after the value: byte {byte:#04x} at offset {}",
109 self.lexer.pos()
110 ))),
111 Err(other) => Err(other),
112 }
113 }
114
115 pub(crate) fn enter_recursion(&mut self) -> Result<(), YsonError> {
116 self.depth += 1;
117 if self.depth > self.max_depth {
118 return Err(YsonError::Custom("Recursion limit exceeded".into()));
119 }
120 Ok(())
121 }
122
123 pub(crate) fn leave_recursion(&mut self) {
124 self.depth -= 1;
125 }
126
127 fn skip_attributes(&mut self) -> Result<(), YsonError> {
128 if self.lexer.peek_byte()? == b'<' {
129 self.enter_recursion()?;
130 self.lexer.next_token()?;
131 let mut attr_depth = 1;
132 while attr_depth > 0 {
133 match self.lexer.next_token()? {
134 Token::BeginAttributes => attr_depth += 1,
135 Token::EndAttributes => attr_depth -= 1,
136 _ => {}
137 }
138 if attr_depth > self.max_depth {
139 return Err(YsonError::Custom("Attributes nesting too deep".into()));
140 }
141 }
142 self.leave_recursion();
143 }
144 Ok(())
145 }
146}
147
148macro_rules! delegate_skip_attributes {
149 ( $($method:ident),* $(,)? ) => {
150 $(
151 fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
152 where
153 V: Visitor<'de>,
154 {
155 if !self.is_reading_attributes {
156 self.skip_attributes()?;
157 }
158 self.deserialize_any(visitor)
159 }
160 )*
161 };
162}
163
164impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
165 type Error = YsonError;
166
167 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
168 where
169 V: Visitor<'de>,
170 {
171 let was_reading_attributes = self.is_reading_attributes;
172 self.is_reading_attributes = false;
173
174 if was_reading_attributes {
175 if self.lexer.peek_byte()? != b'<' {
176 return visitor.visit_map(EmptyMapAccess);
177 }
178 self.lexer.next_token()?;
179 return visitor.visit_map(CommaSeparated::new(self, b'>')?);
180 }
181
182 if self.lexer.peek_byte()? == b'<' {
183 return visitor.visit_map(FlatStructAccess::new(self)?);
184 }
185
186 match self.lexer.next_token()? {
187 Token::Entity => visitor.visit_unit(),
188 Token::Boolean(b) => visitor.visit_bool(b),
189 Token::Int64(i) => visitor.visit_i64(i),
190 Token::Uint64(u) => visitor.visit_u64(u),
191 Token::Double(d) => visitor.visit_f64(d),
192 Token::String(s) => match s {
193 Cow::Borrowed(b) => {
194 if let Ok(utf8) = std::str::from_utf8(b) {
195 visitor.visit_borrowed_str(utf8)
196 } else {
197 visitor.visit_borrowed_bytes(b)
198 }
199 }
200 Cow::Owned(vec) => match String::from_utf8(vec) {
201 Ok(utf8) => visitor.visit_string(utf8),
202 Err(e) => visitor.visit_byte_buf(e.into_bytes()),
203 },
204 },
205 Token::BeginList => {
206 let value = visitor.visit_seq(CommaSeparated::new(&mut *self, b']')?)?;
207 self.end_container(b']')?;
208 Ok(value)
209 }
210 Token::BeginMap => {
211 let value = visitor.visit_map(CommaSeparated::new(&mut *self, b'}')?)?;
212 self.end_container(b'}')?;
213 Ok(value)
214 }
215 Token::BeginAttributes => {
216 let value = visitor.visit_map(CommaSeparated::new(&mut *self, b'>')?)?;
217 self.end_container(b'>')?;
218 Ok(value)
219 }
220 t => Err(YsonError::Custom(format!("Unexpected token: {t:?}"))),
221 }
222 }
223
224 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
225 where
226 V: Visitor<'de>,
227 {
228 let was_reading_attributes = self.is_reading_attributes;
229 self.is_reading_attributes = false;
230
231 if was_reading_attributes {
232 if self.lexer.peek_byte()? == b'<' {
233 self.is_reading_attributes = true;
234 let res = visitor.visit_some(&mut *self);
235 self.is_reading_attributes = false;
236 res
237 } else {
238 visitor.visit_none()
239 }
240 } else {
241 self.skip_attributes()?;
242 if self.lexer.peek_byte()? == b'#' {
243 self.lexer.next_token()?;
244 visitor.visit_none()
245 } else {
246 visitor.visit_some(self)
247 }
248 }
249 }
250
251 fn deserialize_struct<V>(
252 self,
253 name: &'static str,
254 fields: &'static [&'static str],
255 visitor: V,
256 ) -> Result<V::Value, Self::Error>
257 where
258 V: Visitor<'de>,
259 {
260 if name == "$__yson_attributes" {
261 return visitor.visit_seq(AttributesWrapperAccess::new(self)?);
262 }
263 if fields.iter().any(|f| f.starts_with('@')) {
264 return visitor.visit_map(FlatStructAccess::new(self)?);
265 }
266
267 if !self.is_reading_attributes {
268 self.skip_attributes()?;
269 }
270 self.deserialize_any(visitor)
271 }
272
273 fn deserialize_enum<V>(
274 self,
275 _name: &'static str,
276 _variants: &'static [&'static str],
277 visitor: V,
278 ) -> Result<V::Value, Self::Error>
279 where
280 V: Visitor<'de>,
281 {
282 if !self.is_reading_attributes {
283 self.skip_attributes()?;
284 }
285
286 let peeked = self.lexer.peek_byte()?;
287 if peeked == b'{' {
288 self.lexer.next_token()?;
289 let val = visitor.visit_enum(EnumAccess::new(self, true))?;
290
291 loop {
292 match self.lexer.peek_byte() {
293 Ok(b';' | b'}') => break,
294 Ok(_) => {
295 self.lexer.next_token()?;
296 }
297 Err(_) => break,
298 }
299 }
300
301 if let Ok(b';') = self.lexer.peek_byte() {
302 self.lexer.next_token()?;
303 }
304
305 match self.lexer.next_token()? {
306 Token::EndMap => Ok(val),
307 t => Err(YsonError::Custom(format!(
308 "Expected '}}' after variant, got {t:?}"
309 ))),
310 }
311 } else {
312 visitor.visit_enum(EnumAccess::new(self, false))
313 }
314 }
315
316 delegate_skip_attributes! {
317 deserialize_bool, deserialize_i8, deserialize_i16, deserialize_i32,
318 deserialize_i64, deserialize_i128, deserialize_u8, deserialize_u16,
319 deserialize_u32, deserialize_u64, deserialize_u128, deserialize_f32,
320 deserialize_f64, deserialize_char, deserialize_str, deserialize_string,
321 deserialize_bytes, deserialize_byte_buf, deserialize_unit,
322 deserialize_seq, deserialize_map, deserialize_identifier,
323 deserialize_ignored_any
324 }
325
326 fn deserialize_unit_struct<V>(
327 self,
328 _name: &'static str,
329 visitor: V,
330 ) -> Result<V::Value, Self::Error>
331 where
332 V: Visitor<'de>,
333 {
334 if !self.is_reading_attributes {
335 self.skip_attributes()?;
336 }
337 self.deserialize_any(visitor)
338 }
339
340 fn deserialize_newtype_struct<V>(
341 self,
342 _name: &'static str,
343 visitor: V,
344 ) -> Result<V::Value, Self::Error>
345 where
346 V: Visitor<'de>,
347 {
348 if !self.is_reading_attributes {
349 self.skip_attributes()?;
350 }
351 self.deserialize_any(visitor)
352 }
353
354 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
355 where
356 V: Visitor<'de>,
357 {
358 if !self.is_reading_attributes {
359 self.skip_attributes()?;
360 }
361 self.deserialize_any(visitor)
362 }
363
364 fn deserialize_tuple_struct<V>(
365 self,
366 _name: &'static str,
367 _len: usize,
368 visitor: V,
369 ) -> Result<V::Value, Self::Error>
370 where
371 V: Visitor<'de>,
372 {
373 if !self.is_reading_attributes {
374 self.skip_attributes()?;
375 }
376 self.deserialize_any(visitor)
377 }
378}
379
380pub struct StreamDeserializer<'de, T> {
401 de: Deserializer<'de>,
402 first: bool,
403 _marker: std::marker::PhantomData<T>,
404}
405
406impl<'de, T> StreamDeserializer<'de, T>
407where
408 T: de::Deserialize<'de>,
409{
410 #[must_use]
417 pub fn new(input: &'de [u8], is_binary: bool) -> Self {
418 Self {
419 de: Deserializer::from_bytes(input, is_binary),
420 first: true,
421 _marker: std::marker::PhantomData,
422 }
423 }
424
425 pub fn next_item(&mut self) -> Result<Option<T>, YsonError> {
440 let peek_res = self.de.lexer.peek_byte();
441
442 if matches!(peek_res, Err(YsonError::Eof)) {
443 return Ok(None);
444 }
445
446 let next_byte = peek_res?;
447
448 if self.first {
449 self.first = false;
450 } else if next_byte == b';' {
451 self.de.lexer.next_token()?;
452 if matches!(self.de.lexer.peek_byte(), Err(YsonError::Eof)) {
453 return Ok(None);
454 }
455 }
456
457 let item = T::deserialize(&mut self.de)?;
458 Ok(Some(item))
459 }
460}
461
462struct MapKey(Vec<u8>);
469
470impl<'de> Deserialize<'de> for MapKey {
471 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
472 where
473 D: de::Deserializer<'de>,
474 {
475 struct MapKeyVisitor;
476
477 impl Visitor<'_> for MapKeyVisitor {
478 type Value = MapKey;
479
480 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
481 formatter.write_str("a YSON map key (byte string)")
482 }
483
484 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
485 Ok(MapKey(v.as_bytes().to_vec()))
486 }
487
488 fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
489 Ok(MapKey(v.into_bytes()))
490 }
491
492 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
493 Ok(MapKey(v.to_vec()))
494 }
495
496 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
497 Ok(MapKey(v))
498 }
499 }
500
501 deserializer.deserialize_any(MapKeyVisitor)
502 }
503}
504
505macro_rules! impl_visit_primitives {
506 ( $( $method:ident ( $v_type:ty ) => $node_variant:ident ),* ) => {
507 $(
508 fn $method<E>(self, v: $v_type) -> Result<Self::Value, E> {
509 Ok(YsonValue {
510 attributes: None,
511 node: YsonNode::$node_variant(v),
512 })
513 }
514 )*
515 };
516}
517
518impl<'de> Deserialize<'de> for YsonValue {
519 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
520 where
521 D: de::Deserializer<'de>,
522 {
523 struct YsonValueVisitor;
524
525 impl<'de> Visitor<'de> for YsonValueVisitor {
526 type Value = YsonValue;
527
528 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
529 formatter.write_str("any YSON value")
530 }
531
532 impl_visit_primitives! {
533 visit_bool(bool) => Boolean,
534 visit_i64(i64) => Int64,
535 visit_u64(u64) => Uint64,
536 visit_f64(f64) => Double
537 }
538
539 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
540 Ok(YsonValue {
541 attributes: None,
542 node: YsonNode::String(v.as_bytes().to_vec()),
543 })
544 }
545
546 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
547 Ok(YsonValue {
548 attributes: None,
549 node: YsonNode::String(v.to_vec()),
550 })
551 }
552
553 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
554 Ok(YsonValue {
555 attributes: None,
556 node: YsonNode::String(v),
557 })
558 }
559
560 fn visit_unit<E>(self) -> Result<Self::Value, E> {
561 Ok(YsonValue {
562 attributes: None,
563 node: YsonNode::Entity,
564 })
565 }
566
567 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
568 where
569 A: SeqAccess<'de>,
570 {
571 let mut vec = Vec::new();
572 while let Some(elem) = seq.next_element()? {
573 vec.push(elem);
574 }
575 Ok(YsonValue {
576 attributes: None,
577 node: YsonNode::List(vec),
578 })
579 }
580
581 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
582 where
583 M: MapAccess<'de>,
584 {
585 let mut attributes = BTreeMap::new();
586 let mut plain_map = BTreeMap::new();
587 let mut body_node = None;
588 let mut is_attributed = false;
589
590 while let Some(MapKey(key)) = map.next_key::<MapKey>()? {
591 if let Some(attr_name) = key.strip_prefix(b"@") {
592 is_attributed = true;
593 attributes.insert(attr_name.to_vec(), map.next_value()?);
594 } else if key == b"$value" {
595 is_attributed = true;
596 let val: YsonValue = map.next_value()?;
597 body_node = Some(val.node);
598 if let Some(inner_attrs) = val.attributes {
599 attributes.extend(inner_attrs);
600 }
601 } else {
602 plain_map.insert(key, map.next_value()?);
603 }
604 }
605
606 if is_attributed {
607 if !plain_map.is_empty() {
615 if body_node.is_some() {
616 let (key, _) = plain_map.iter().next().expect("checked non-empty");
617 return Err(serde::de::Error::custom(format!(
618 "map carries \"$value\" beside a plain key {:?}; \
619 one value cannot have two bodies",
620 String::from_utf8_lossy(key)
621 )));
622 }
623 body_node = Some(YsonNode::Map(plain_map));
624 }
625 Ok(YsonValue {
626 attributes: if attributes.is_empty() {
627 None
628 } else {
629 Some(attributes)
630 },
631 node: body_node.unwrap_or(YsonNode::Entity),
632 })
633 } else {
634 Ok(YsonValue {
635 attributes: None,
636 node: YsonNode::Map(plain_map),
637 })
638 }
639 }
640 }
641
642 deserializer.deserialize_any(YsonValueVisitor)
643 }
644}