1
use std::borrow::Cow;
2
use std::collections::VecDeque;
3
use std::fmt::Debug;
4
use std::io::Read;
5
use std::ops::{Deref, Range};
6
use std::str;
7

            
8
use byteorder::ReadBytesExt;
9
use format::Kind;
10
use serde::de::{
11
    self, DeserializeSeed, EnumAccess, Error as _, MapAccess, SeqAccess, VariantAccess, Visitor,
12
};
13
use serde::ser::SerializeSeq;
14
use serde::{Deserialize, Serialize};
15
#[cfg(feature = "tracing")]
16
use tracing::instrument;
17

            
18
use crate::format::{
19
    self, Atom, Float, InnerFloat, InnerInteger, Integer, Nucleus, CURRENT_VERSION,
20
};
21
use crate::reader::{BufferedBytes, IoReader, Reader, SliceReader};
22
use crate::{Error, Result};
23

            
24
/// Deserializer for the Pot format.
25
pub struct Deserializer<'s, 'de, R: Reader<'de>> {
26
    input: R,
27
    symbols: SymbolMapRef<'s, 'de>,
28
    peeked_atom: VecDeque<Atom<'de>>,
29
    remaining_budget: usize,
30
    scratch: Vec<u8>,
31
}
32

            
33
impl<'s, 'de, R: Reader<'de>> Debug for Deserializer<'s, 'de, R> {
34
1425
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35
1425
        f.debug_struct("Deserializer")
36
1425
            .field("symbols", &self.symbols)
37
1425
            .field("peeked_atom", &self.peeked_atom)
38
1425
            .field("remaining_budget", &self.remaining_budget)
39
1425
            .finish()
40
1425
    }
41
}
42

            
43
impl<'s, 'de> Deserializer<'s, 'de, SliceReader<'de>> {
44
    /// Returns a new deserializer for `input`.
45
    #[inline]
46
136
    pub(crate) fn from_slice(input: &'de [u8], maximum_bytes_allocatable: usize) -> Result<Self> {
47
136
        Self::from_slice_with_symbols(input, SymbolMapRef::temporary(), maximum_bytes_allocatable)
48
136
    }
49

            
50
168
    fn from_slice_with_symbols(
51
168
        input: &'de [u8],
52
168
        symbols: SymbolMapRef<'s, 'de>,
53
168
        maximum_bytes_allocatable: usize,
54
168
    ) -> Result<Self> {
55
168
        Self::new(SliceReader::from(input), symbols, maximum_bytes_allocatable)
56
168
    }
57

            
58
    /// Returns `true` if the input has been consumed completely.
59
    #[must_use]
60
    #[inline]
61
123
    pub fn end_of_input(&self) -> bool {
62
123
        self.input.data.is_empty() && self.peeked_atom.is_empty()
63
123
    }
64
}
65

            
66
impl<'s, 'de, R: ReadBytesExt> Deserializer<'s, 'de, IoReader<R>> {
67
    /// Returns a new deserializer for `input`.
68
    #[inline]
69
60
    pub(crate) fn from_read(
70
60
        input: R,
71
60
        symbols: SymbolMapRef<'s, 'de>,
72
60
        maximum_bytes_allocatable: usize,
73
60
    ) -> Result<Self> {
74
60
        Self::new(IoReader::new(input), symbols, maximum_bytes_allocatable)
75
60
    }
76
}
77

            
78
impl<'s, 'de, R: Reader<'de>> Deserializer<'s, 'de, R> {
79
    #[inline]
80
228
    pub(crate) fn new(
81
228
        input: R,
82
228
        symbols: SymbolMapRef<'s, 'de>,
83
228
        maximum_bytes_allocatable: usize,
84
228
    ) -> Result<Self> {
85
228
        let mut deserializer = Deserializer {
86
228
            input,
87
228
            symbols,
88
228
            peeked_atom: VecDeque::new(),
89
228
            remaining_budget: maximum_bytes_allocatable,
90
228
            scratch: Vec::new(),
91
228
        };
92
228
        deserializer.read_header()?;
93
227
        Ok(deserializer)
94
228
    }
95

            
96
228
    fn read_header(&mut self) -> Result<()> {
97
228
        let version = format::read_header(&mut self.input)?;
98
228
        if version == CURRENT_VERSION {
99
227
            Ok(())
100
        } else {
101
1
            Err(Error::IncompatibleVersion)
102
        }
103
228
    }
104

            
105
    fn read_atom(&mut self) -> Result<Atom<'de>> {
106
170779
        if let Some(peeked) = self.peeked_atom.pop_front() {
107
10020
            Ok(peeked)
108
        } else {
109
160759
            format::read_atom(
110
160759
                &mut self.input,
111
160759
                &mut self.remaining_budget,
112
160759
                &mut self.scratch,
113
160759
            )
114
        }
115
170779
    }
116

            
117
    #[allow(clippy::missing_panics_doc)]
118
10020
    fn peek_atom_at(&mut self, index: usize) -> Result<&Atom<'_>> {
119
20040
        while index >= self.peeked_atom.len() {
120
10020
            let atom = self.read_atom()?;
121
10020
            self.peeked_atom.push_back(atom);
122
        }
123

            
124
10020
        Ok(&self.peeked_atom[index])
125
10020
    }
126

            
127
    #[allow(clippy::missing_panics_doc)]
128
10020
    fn peek_atom(&mut self) -> Result<&Atom<'_>> {
129
10020
        self.peek_atom_at(0)
130
10020
    }
131

            
132
160293
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
133
    #[allow(clippy::cast_possible_truncation)]
134
    fn visit_symbol<V>(&mut self, atom: &Atom<'_>, visitor: V) -> Result<V::Value>
135
    where
136
        V: Visitor<'de>,
137
    {
138
        let is_id = atom.arg & 0b1 != 0;
139
        let arg = atom.arg >> 1;
140
        if is_id {
141
            self.symbols.visit_symbol_id(arg, visitor)
142
        } else {
143
            // New symbol
144
            let name = self
145
                .input
146
                .buffered_read_bytes(arg as usize, &mut self.scratch)?;
147
            match name {
148
                BufferedBytes::Data(name) => {
149
                    let name = str::from_utf8(name)?;
150
                    self.symbols.push_borrowed(name);
151
                    visitor.visit_borrowed_str(name)
152
                }
153
                BufferedBytes::Scratch => {
154
                    let name = str::from_utf8(&self.scratch)?;
155
                    let result = visitor.visit_str(name);
156
                    self.symbols.push(name);
157
                    result
158
                }
159
            }
160
        }
161
    }
162
}
163

            
164
impl<'a, 'de, 's, R: Reader<'de>> de::Deserializer<'de> for &'a mut Deserializer<'s, 'de, R> {
165
    type Error = Error;
166

            
167
    #[inline]
168
1
    fn is_human_readable(&self) -> bool {
169
1
        false
170
1
    }
171

            
172
    // Look at the input data to decide what Serde data model type to
173
    // deserialize as. Not all data formats are able to support this operation.
174
    // Formats that support `deserialize_any` are known as self-describing.
175
43
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
176
    #[allow(clippy::cast_possible_truncation)]
177
    #[inline]
178
    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
179
    where
180
        V: Visitor<'de>,
181
    {
182
        let atom = self.read_atom()?;
183

            
184
        match atom.kind {
185
            Kind::Special => match &atom.nucleus {
186
                Some(Nucleus::Boolean(value)) => visitor.visit_bool(*value),
187
                Some(Nucleus::Unit) => visitor.visit_unit(),
188
                Some(Nucleus::Named) => visitor.visit_map(AtomList::new(self, Some(1))),
189
                Some(Nucleus::DynamicMap) => visitor.visit_map(AtomList::new(self, None)),
190
                Some(Nucleus::DynamicEnd) => Err(Error::custom("unexpected dynamic end")),
191
                Some(Nucleus::Bytes(_) | Nucleus::Integer(_) | Nucleus::Float(_)) => {
192
                    unreachable!("read_atom can't return this nucleus as a Special")
193
                }
194
                None => visitor.visit_none(),
195
            },
196
            Kind::Int => match atom.nucleus {
197
                Some(Nucleus::Integer(Integer(InnerInteger::I8(value)))) => visitor.visit_i8(value),
198
                Some(Nucleus::Integer(Integer(InnerInteger::I16(value)))) => {
199
                    visitor.visit_i16(value)
200
                }
201
                Some(Nucleus::Integer(Integer(InnerInteger::I32(value)))) => {
202
                    visitor.visit_i32(value)
203
                }
204
                Some(Nucleus::Integer(Integer(InnerInteger::I64(value)))) => {
205
                    visitor.visit_i64(value)
206
                }
207
                Some(Nucleus::Integer(Integer(InnerInteger::I128(value)))) => {
208
                    visitor.visit_i128(value)
209
                }
210
                _ => unreachable!("read_atom should never return anything else"),
211
            },
212
            Kind::UInt => match atom.nucleus {
213
                Some(Nucleus::Integer(Integer(InnerInteger::U8(value)))) => visitor.visit_u8(value),
214
                Some(Nucleus::Integer(Integer(InnerInteger::U16(value)))) => {
215
                    visitor.visit_u16(value)
216
                }
217
                Some(Nucleus::Integer(Integer(InnerInteger::U32(value)))) => {
218
                    visitor.visit_u32(value)
219
                }
220
                Some(Nucleus::Integer(Integer(InnerInteger::U64(value)))) => {
221
                    visitor.visit_u64(value)
222
                }
223
                Some(Nucleus::Integer(Integer(InnerInteger::U128(value)))) => {
224
                    visitor.visit_u128(value)
225
                }
226
                _ => unreachable!("read_atom should never return anything else"),
227
            },
228
            Kind::Float => match atom.nucleus {
229
                Some(Nucleus::Float(Float(InnerFloat::F32(value)))) => visitor.visit_f32(value),
230
                Some(Nucleus::Float(Float(InnerFloat::F64(value)))) => visitor.visit_f64(value),
231
                _ => unreachable!("read_atom should never return anything else"),
232
            },
233
            Kind::Sequence => visitor.visit_seq(AtomList::new(self, Some(atom.arg as usize))),
234
            Kind::Map => visitor.visit_map(AtomList::new(self, Some(atom.arg as usize))),
235
            Kind::Symbol => self.visit_symbol(&atom, visitor),
236
            Kind::Bytes => match &atom.nucleus {
237
                Some(Nucleus::Bytes(bytes)) => match bytes {
238
                    BufferedBytes::Data(bytes) => {
239
                        if let Ok(as_str) = str::from_utf8(bytes) {
240
                            visitor.visit_borrowed_str(as_str)
241
                        } else {
242
                            visitor.visit_borrowed_bytes(bytes)
243
                        }
244
                    }
245
                    BufferedBytes::Scratch => {
246
                        if let Ok(as_str) = str::from_utf8(&self.scratch) {
247
                            visitor.visit_str(as_str)
248
                        } else {
249
                            visitor.visit_bytes(&self.scratch)
250
                        }
251
                    }
252
                },
253
                None => visitor.visit_none(),
254
                // The parsing operation guarantees that this will always be bytes.
255
                _ => unreachable!(),
256
            },
257
        }
258
    }
259

            
260
4
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
261
    #[inline]
262
    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
263
    where
264
        V: Visitor<'de>,
265
    {
266
        let atom = self.read_atom()?;
267
        match atom.kind {
268
            Kind::Special | Kind::UInt | Kind::Int => match atom.nucleus {
269
                Some(Nucleus::Integer(integer)) => visitor.visit_bool(!integer.is_zero()),
270
                Some(Nucleus::Boolean(b)) => visitor.visit_bool(b),
271
                Some(Nucleus::Unit) | None => visitor.visit_bool(false),
272
                other => Err(Error::custom(format!(
273
                    "expected bool nucleus, got {other:?}"
274
                ))),
275
            },
276
            other => Err(Error::custom(format!("expected bool, got {other:?}"))),
277
        }
278
    }
279

            
280
16
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
281
    #[inline]
282
    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
283
    where
284
        V: Visitor<'de>,
285
    {
286
        let atom = self.read_atom()?;
287
        match atom.kind {
288
            Kind::UInt | Kind::Int => {
289
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
290
                    visitor.visit_i8(integer.as_i8()?)
291
                } else {
292
                    unreachable!("read_atom should never return anything else")
293
                }
294
            }
295
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
296
                visitor.visit_i8(0)
297
            }
298
            other => Err(Error::custom(format!("expected i8, got {other:?}"))),
299
        }
300
    }
301

            
302
16
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
303
    #[inline]
304
    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
305
    where
306
        V: Visitor<'de>,
307
    {
308
        let atom = self.read_atom()?;
309
        match atom.kind {
310
            Kind::UInt | Kind::Int => {
311
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
312
                    visitor.visit_i16(integer.as_i16()?)
313
                } else {
314
                    unreachable!("read_atom should never return anything else")
315
                }
316
            }
317
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
318
                visitor.visit_i16(0)
319
            }
320
            other => Err(Error::custom(format!("expected i16, got {other:?}"))),
321
        }
322
    }
323

            
324
21
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
325
    #[inline]
326
    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
327
    where
328
        V: Visitor<'de>,
329
    {
330
        let atom = self.read_atom()?;
331
        match atom.kind {
332
            Kind::UInt | Kind::Int => {
333
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
334
                    visitor.visit_i32(integer.as_i32()?)
335
                } else {
336
                    unreachable!("read_atom should never return anything else")
337
                }
338
            }
339
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
340
                visitor.visit_i32(0)
341
            }
342
            other => Err(Error::custom(format!("expected i32, got {other:?}"))),
343
        }
344
    }
345

            
346
16
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
347
    #[inline]
348
    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
349
    where
350
        V: Visitor<'de>,
351
    {
352
        let atom = self.read_atom()?;
353
        match atom.kind {
354
            Kind::UInt | Kind::Int => {
355
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
356
                    visitor.visit_i64(integer.as_i64()?)
357
                } else {
358
                    unreachable!("read_atom should never return anything else")
359
                }
360
            }
361
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
362
                visitor.visit_i64(0)
363
            }
364
            other => Err(Error::custom(format!("expected i64, got {other:?}"))),
365
        }
366
    }
367

            
368
62
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
369
    #[inline]
370
    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
371
    where
372
        V: Visitor<'de>,
373
    {
374
        let atom = self.read_atom()?;
375
        match atom.kind {
376
            Kind::UInt | Kind::Int => {
377
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
378
                    visitor.visit_i128(integer.as_i128()?)
379
                } else {
380
                    unreachable!("read_atom should never return anything else")
381
                }
382
            }
383
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
384
                visitor.visit_i128(0)
385
            }
386
            other => Err(Error::custom(format!("expected i128, got {other:?}"))),
387
        }
388
    }
389

            
390
38
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
391
    #[inline]
392
    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
393
    where
394
        V: Visitor<'de>,
395
    {
396
        let atom = self.read_atom()?;
397
        match atom.kind {
398
            Kind::UInt | Kind::Int => {
399
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
400
                    visitor.visit_u8(integer.as_u8()?)
401
                } else {
402
                    unreachable!("read_atom should never return anything else")
403
                }
404
            }
405
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
406
                visitor.visit_u8(0)
407
            }
408
            other => Err(Error::custom(format!("expected u8, got {other:?}"))),
409
        }
410
    }
411

            
412
20022
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
413
    #[inline]
414
    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
415
    where
416
        V: Visitor<'de>,
417
    {
418
        let atom = self.read_atom()?;
419
        match atom.kind {
420
            Kind::UInt | Kind::Int => {
421
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
422
                    visitor.visit_u16(integer.as_u16()?)
423
                } else {
424
                    unreachable!("read_atom should never return anything else")
425
                }
426
            }
427
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
428
                visitor.visit_u16(0)
429
            }
430
            other => Err(Error::custom(format!("expected u16, got {other:?}"))),
431
        }
432
    }
433

            
434
19
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
435
    #[inline]
436
    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
437
    where
438
        V: Visitor<'de>,
439
    {
440
        let atom = self.read_atom()?;
441
        match atom.kind {
442
            Kind::UInt | Kind::Int => {
443
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
444
                    visitor.visit_u32(integer.as_u32()?)
445
                } else {
446
                    unreachable!("read_atom should never return anything else")
447
                }
448
            }
449
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
450
                visitor.visit_u32(0)
451
            }
452
            other => Err(Error::custom(format!("expected u32, got {other:?}"))),
453
        }
454
    }
455

            
456
20050
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
457
    #[inline]
458
    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
459
    where
460
        V: Visitor<'de>,
461
    {
462
        let atom = self.read_atom()?;
463
        match atom.kind {
464
            Kind::UInt | Kind::Int => {
465
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
466
                    visitor.visit_u64(integer.as_u64()?)
467
                } else {
468
                    unreachable!("read_atom should never return anything else")
469
                }
470
            }
471
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
472
                visitor.visit_u64(0)
473
            }
474
            other => Err(Error::custom(format!("expected u64, got {other:?}"))),
475
        }
476
    }
477

            
478
42
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
479
    #[inline]
480
    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
481
    where
482
        V: Visitor<'de>,
483
    {
484
        let atom = self.read_atom()?;
485
        match atom.kind {
486
            Kind::UInt | Kind::Int => {
487
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
488
                    visitor.visit_u128(integer.as_u128()?)
489
                } else {
490
                    unreachable!("read_atom should never return anything else")
491
                }
492
            }
493
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
494
                visitor.visit_u128(0)
495
            }
496
            other => Err(Error::custom(format!("expected i64, got {other:?}"))),
497
        }
498
    }
499

            
500
17
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
501
    #[inline]
502
    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
503
    where
504
        V: Visitor<'de>,
505
    {
506
        let atom = self.read_atom()?;
507
        match atom.kind {
508
            Kind::Int => {
509
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
510
                    visitor.visit_f32(integer.as_f32()?)
511
                } else {
512
                    unreachable!("read_atom should never return anything else")
513
                }
514
            }
515

            
516
            Kind::Float => {
517
                if let Some(Nucleus::Float(float)) = atom.nucleus {
518
                    visitor.visit_f32(float.as_f32()?)
519
                } else {
520
                    unreachable!("read_atom should never return anything else")
521
                }
522
            }
523
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
524
                visitor.visit_f32(0.)
525
            }
526
            other => Err(Error::custom(format!("expected f32, got {other:?}"))),
527
        }
528
    }
529

            
530
24
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
531
    #[inline]
532
    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
533
    where
534
        V: Visitor<'de>,
535
    {
536
        let atom = self.read_atom()?;
537
        match atom.kind {
538
            Kind::Int => {
539
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
540
                    visitor.visit_f64(integer.as_f64()?)
541
                } else {
542
                    unreachable!("read_atom should never return anything else")
543
                }
544
            }
545

            
546
            Kind::Float => {
547
                if let Some(Nucleus::Float(float)) = atom.nucleus {
548
                    visitor.visit_f64(float.as_f64())
549
                } else {
550
                    unreachable!("read_atom should never return anything else")
551
                }
552
            }
553
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
554
                visitor.visit_f64(0.)
555
            }
556
            other => Err(Error::custom(format!("expected f64, got {other:?}"))),
557
        }
558
    }
559

            
560
15
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
561
    #[inline]
562
    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
563
    where
564
        V: Visitor<'de>,
565
    {
566
        let atom = self.read_atom()?;
567
        match atom.kind {
568
            Kind::UInt | Kind::Int => {
569
                if let Some(Nucleus::Integer(integer)) = atom.nucleus {
570
                    visitor.visit_char(
571
                        char::from_u32(integer.as_u32()?)
572
1
                            .ok_or_else(|| Error::InvalidUtf8(String::from("invalid char")))?,
573
                    )
574
                } else {
575
                    unreachable!("read_atom should never return anything else")
576
                }
577
            }
578
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
579
                visitor.visit_char('\0')
580
            }
581
            other => Err(Error::custom(format!("expected char, got {other:?}"))),
582
        }
583
    }
584

            
585
69928
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
586
    #[inline]
587
    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
588
    where
589
        V: Visitor<'de>,
590
    {
591
        let atom = self.read_atom()?;
592
        match atom.kind {
593
            Kind::Bytes => match atom.nucleus {
594
                Some(Nucleus::Bytes(bytes)) => match bytes {
595
                    BufferedBytes::Data(bytes) => {
596
                        visitor.visit_borrowed_str(str::from_utf8(bytes)?)
597
                    }
598
                    BufferedBytes::Scratch => visitor.visit_str(str::from_utf8(&self.scratch)?),
599
                },
600
                _ => unreachable!("read_atom should never return anything else"),
601
            },
602
            Kind::Symbol => self.visit_symbol(&atom, visitor),
603
            Kind::Special => {
604
                if matches!(atom.nucleus, Some(Nucleus::Named)) {
605
                    // If we encounter a named entity here, skip it and trust that serde will decode the following information correctly.
606
                    self.deserialize_str(visitor)
607
                } else if matches!(atom.nucleus, Some(Nucleus::Unit) | None) {
608
                    visitor.visit_borrowed_str("")
609
                } else {
610
                    self.visit_symbol(&atom, visitor)
611
                }
612
            }
613
            other => Err(Error::custom(format!("expected str, got {other:?}"))),
614
        }
615
    }
616

            
617
49916
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
618
    #[inline]
619
    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
620
    where
621
        V: Visitor<'de>,
622
    {
623
        self.deserialize_str(visitor)
624
    }
625

            
626
16
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
627
    #[allow(clippy::cast_possible_truncation)]
628
    #[inline]
629
    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
630
    where
631
        V: Visitor<'de>,
632
    {
633
        let atom = self.read_atom()?;
634
        match atom.kind {
635
            Kind::Bytes => match atom.nucleus {
636
                Some(Nucleus::Bytes(bytes)) => match bytes {
637
                    BufferedBytes::Data(bytes) => visitor.visit_borrowed_bytes(bytes),
638
                    BufferedBytes::Scratch => visitor.visit_bytes(&self.scratch),
639
                },
640
                _ => unreachable!("read_atom should never return anything else"),
641
            },
642
            Kind::Sequence => {
643
                let mut buffer = Vec::with_capacity(atom.arg as usize);
644
                for _ in 0..atom.arg {
645
                    let atom = self.read_atom()?;
646

            
647
                    if let Some(Nucleus::Integer(integer)) = atom.nucleus {
648
                        buffer.push(integer.as_u8()?);
649
                    } else {
650
                        return Err(Error::custom(
651
                            "expected byte array, encountered non-integer atom",
652
                        ));
653
                    }
654
                }
655
                visitor.visit_byte_buf(buffer)
656
            }
657
            Kind::Special if matches!(atom.nucleus, Some(Nucleus::Unit) | None) => {
658
                visitor.visit_borrowed_bytes(b"")
659
            }
660
            other => Err(Error::custom(format!("expected bytes, got {other:?}"))),
661
        }
662
    }
663

            
664
6
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
665
    #[inline]
666
    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
667
    where
668
        V: Visitor<'de>,
669
    {
670
        self.deserialize_bytes(visitor)
671
    }
672

            
673
20017
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
674
    #[inline]
675
    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
676
    where
677
        V: Visitor<'de>,
678
    {
679
        let atom = self.peek_atom()?;
680
        if matches!(atom.kind, Kind::Special) && atom.nucleus.is_none() {
681
            // Consume the atom.
682
            self.read_atom()?;
683
            return visitor.visit_none();
684
        }
685

            
686
        visitor.visit_some(self)
687
    }
688

            
689
    // In Serde, unit means an anonymous value containing no data.
690
4
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
691
    #[inline]
692
    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
693
    where
694
        V: Visitor<'de>,
695
    {
696
        let atom = self.read_atom()?;
697
        if atom.kind == Kind::Special && matches!(atom.nucleus, Some(Nucleus::Unit)) {
698
            visitor.visit_unit()
699
        } else {
700
            Err(Error::custom(format!("expected unit, got {:?}", atom.kind)))
701
        }
702
    }
703

            
704
    // Unit struct means a named value containing no data.
705
2
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
706
    #[inline]
707
    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
708
    where
709
        V: Visitor<'de>,
710
    {
711
        self.deserialize_unit(visitor)
712
    }
713

            
714
    // As is done here, serializers are encouraged to treat newtype structs as
715
    // insignificant wrappers around the data they contain. That means not
716
    // parsing anything other than the contained value.
717
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
718
    #[inline]
719
    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
720
    where
721
        V: Visitor<'de>,
722
    {
723
        visitor.visit_newtype_struct(self)
724
    }
725

            
726
22
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
727
    #[allow(clippy::cast_possible_truncation)]
728
    #[inline]
729
    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
730
    where
731
        V: Visitor<'de>,
732
    {
733
        let atom = self.read_atom()?;
734
        if atom.kind == Kind::Sequence {
735
            visitor.visit_seq(AtomList::new(self, Some(atom.arg as usize)))
736
        } else if atom.kind == Kind::Special && matches!(atom.nucleus, Some(Nucleus::Unit) | None) {
737
            visitor.visit_seq(EmptyList)
738
        } else {
739
            Err(Error::custom(format!(
740
                "expected sequence, got {:?}",
741
                atom.kind
742
            )))
743
        }
744
    }
745

            
746
2
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
747
    #[inline]
748
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
749
    where
750
        V: Visitor<'de>,
751
    {
752
        self.deserialize_seq(visitor)
753
    }
754

            
755
    #[inline]
756
2
    fn deserialize_tuple_struct<V>(
757
2
        self,
758
2
        _name: &'static str,
759
2
        _len: usize,
760
2
        visitor: V,
761
2
    ) -> Result<V::Value>
762
2
    where
763
2
        V: Visitor<'de>,
764
2
    {
765
2
        self.deserialize_seq(visitor)
766
2
    }
767

            
768
20040
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
769
    #[allow(clippy::cast_possible_truncation)]
770
    #[inline]
771
    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
772
    where
773
        V: Visitor<'de>,
774
    {
775
        let atom = self.read_atom()?;
776
        match (atom.kind, atom.nucleus) {
777
            (Kind::Map, _) => visitor.visit_map(AtomList::new(self, Some(atom.arg as usize))),
778
            (Kind::Special, Some(Nucleus::DynamicMap)) => {
779
                visitor.visit_map(AtomList::new(self, None))
780
            }
781
            (Kind::Special, Some(Nucleus::Unit) | None) => visitor.visit_map(EmptyList),
782
            (kind, _) => Err(Error::custom(format!("expected map, got {kind:?}"))),
783
        }
784
    }
785

            
786
20036
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
787
    #[inline]
788
    fn deserialize_struct<V>(
789
        self,
790
        _name: &'static str,
791
        _fields: &'static [&'static str],
792
        visitor: V,
793
    ) -> Result<V::Value>
794
    where
795
        V: Visitor<'de>,
796
    {
797
        self.deserialize_map(visitor)
798
    }
799

            
800
20020
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
801
    #[inline]
802
    fn deserialize_enum<V>(
803
        self,
804
        _name: &'static str,
805
        _variants: &'static [&'static str],
806
        visitor: V,
807
    ) -> Result<V::Value>
808
    where
809
        V: Visitor<'de>,
810
    {
811
        visitor.visit_enum(self)
812
    }
813

            
814
160294
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
815
    #[allow(clippy::cast_possible_truncation)]
816
    #[inline]
817
    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
818
    where
819
        V: Visitor<'de>,
820
    {
821
        let atom = self.read_atom()?;
822
        match atom.kind {
823
            Kind::Symbol => self.visit_symbol(&atom, visitor),
824
            Kind::Bytes => {
825
                if let Some(Nucleus::Bytes(bytes)) = atom.nucleus {
826
                    let as_str = str::from_utf8(bytes.as_slice(&self.scratch))
827
1
                        .map_err(|err| Error::InvalidUtf8(err.to_string()))?;
828
                    visitor.visit_str(as_str)
829
                } else {
830
                    unreachable!("read_atom shouldn't return anything else")
831
                }
832
            }
833
            other => Err(Error::custom(format!("expected identifier, got {other:?}"))),
834
        }
835
    }
836

            
837
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
838
    #[inline]
839
    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
840
    where
841
        V: Visitor<'de>,
842
    {
843
        self.deserialize_any(visitor)
844
    }
845
}
846

            
847
struct EmptyList;
848

            
849
impl<'de> MapAccess<'de> for EmptyList {
850
    type Error = Error;
851

            
852
    #[inline]
853
1
    fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>>
854
1
    where
855
1
        K: DeserializeSeed<'de>,
856
1
    {
857
1
        Ok(None)
858
1
    }
859

            
860
    #[inline]
861
    fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value>
862
    where
863
        V: DeserializeSeed<'de>,
864
    {
865
        unreachable!()
866
    }
867
}
868

            
869
impl<'de> SeqAccess<'de> for EmptyList {
870
    type Error = Error;
871

            
872
    #[inline]
873
    fn next_element_seed<T>(&mut self, _seed: T) -> Result<Option<T::Value>>
874
    where
875
        T: DeserializeSeed<'de>,
876
    {
877
        Ok(None)
878
    }
879
}
880

            
881
struct AtomList<'a, 's, 'de, R: Reader<'de>> {
882
    de: &'a mut Deserializer<'s, 'de, R>,
883
    consumed: usize,
884
    count: Option<usize>,
885
    eof: bool,
886
}
887

            
888
impl<'a, 's, 'de, R: Reader<'de>> AtomList<'a, 's, 'de, R> {
889
10053
    fn new(de: &'a mut Deserializer<'s, 'de, R>, count: Option<usize>) -> Self {
890
10053
        Self {
891
10053
            de,
892
10053
            count,
893
10053
            consumed: 0,
894
10053
            eof: false,
895
10053
        }
896
10053
    }
897

            
898
90334
    fn check_is_eof(&mut self) -> Result<bool> {
899
90334
        if self.eof {
900
            return Ok(true);
901
90334
        } else if let Some(count) = self.count {
902
90328
            if count == self.consumed {
903
10043
                self.eof = true;
904
10043
                return Ok(true);
905
80285
            }
906
        } else {
907
6
            let atom = self.de.peek_atom()?;
908
6
            if matches!(atom.kind, Kind::Special)
909
2
                && matches!(atom.nucleus, Some(Nucleus::DynamicEnd))
910
            {
911
2
                self.eof = true;
912
2
                self.de.read_atom()?;
913
2
                return Ok(true);
914
4
            }
915
        }
916

            
917
80289
        Ok(false)
918
90334
    }
919
}
920

            
921
impl<'a, 's, 'de, R: Reader<'de>> Debug for AtomList<'a, 's, 'de, R> {
922
488
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
923
488
        f.debug_struct("AtomList")
924
488
            .field("de", &self.de)
925
488
            .field("consumed", &self.consumed)
926
488
            .field("count", &self.count)
927
488
            .field("eof", &self.eof)
928
488
            .finish()
929
488
    }
930
}
931

            
932
impl<'a, 's, 'de, R: Reader<'de>> SeqAccess<'de> for AtomList<'a, 's, 'de, R> {
933
    type Error = Error;
934

            
935
20066
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(seed)))]
936
    #[inline]
937
    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
938
    where
939
        T: DeserializeSeed<'de>,
940
    {
941
        if self.check_is_eof()? {
942
            Ok(None)
943
        } else {
944
            self.consumed += 1;
945
            seed.deserialize(&mut *self.de).map(Some)
946
        }
947
    }
948

            
949
    #[inline]
950
12
    fn size_hint(&self) -> Option<usize> {
951
12
        self.count
952
12
    }
953
}
954

            
955
impl<'a, 's, 'de, R: Reader<'de>> MapAccess<'de> for AtomList<'a, 's, 'de, R> {
956
    type Error = Error;
957

            
958
160323
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(seed)))]
959
    #[inline]
960
    fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
961
    where
962
        T: DeserializeSeed<'de>,
963
    {
964
        if self.check_is_eof()? {
965
            Ok(None)
966
        } else {
967
            self.consumed += 1;
968
            seed.deserialize(&mut *self.de).map(Some)
969
        }
970
    }
971

            
972
140281
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(seed)))]
973
    #[inline]
974
    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
975
    where
976
        V: DeserializeSeed<'de>,
977
    {
978
        // Deserialize a map value.
979
        seed.deserialize(&mut *self.de)
980
    }
981

            
982
    #[inline]
983
4
    fn size_hint(&self) -> Option<usize> {
984
4
        self.count
985
4
    }
986
}
987

            
988
impl<'a, 's, 'de, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'s, 'de, R> {
989
    type Error = Error;
990
    type Variant = Self;
991

            
992
20020
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(seed)))]
993
    #[inline]
994
    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
995
    where
996
        V: DeserializeSeed<'de>,
997
    {
998
        // Have the seed deserialize the next atom, which should be the symbol.
999
        let atom = self.read_atom()?;
        if atom.kind == Kind::Special && matches!(atom.nucleus, Some(Nucleus::Named)) {
            let val = seed.deserialize(&mut *self)?;
            Ok((val, self))
        } else {
            Err(Error::custom(format!(
                "expected Named, got {:?}",
                atom.kind
            )))
        }
    }
}

            
impl<'a, 's, 'de, R: Reader<'de>> VariantAccess<'de> for &'a mut Deserializer<'s, 'de, R> {
    type Error = Error;

            
20012
    #[cfg_attr(feature = "tracing", instrument)]
10008
    #[inline]
    fn unit_variant(self) -> Result<()> {
        Ok(())
    }

            
2
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(seed)))]
    #[inline]
    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
    where
        T: DeserializeSeed<'de>,
    {
        seed.deserialize(self)
    }

            
2
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
    #[inline]
    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        de::Deserializer::deserialize_seq(self, visitor)
    }

            
2
    #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(visitor)))]
    #[inline]
    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        de::Deserializer::deserialize_map(self, visitor)
    }
}

            
/// A reference to a [`SymbolList`].
1425
#[derive(Debug)]
pub struct SymbolMapRef<'a, 'de>(SymbolMapRefPrivate<'a, 'de>);

            
1425
#[derive(Debug)]
enum SymbolMapRefPrivate<'a, 'de> {
    /// A reference to a temporary symbol list, which is able to borrow from the
    /// source data.
    Temporary(SymbolList<'de>),
    /// A reference to a persistent symbol list that retains symbols across
    /// multiple deserialization sessions.
    Persistent(&'a mut SymbolMap),
}

            
impl<'a, 'de> SymbolMapRef<'a, 'de> {
209
    pub(crate) const fn temporary() -> Self {
209
        Self(SymbolMapRefPrivate::Temporary(SymbolList::new()))
209
    }

            
    #[allow(clippy::cast_possible_truncation)]
80054
    fn visit_symbol_id<V>(&self, symbol_id: u64, visitor: V) -> Result<V::Value>
80054
    where
80054
        V: Visitor<'de>,
80054
    {
80054
        match &self.0 {
80014
            SymbolMapRefPrivate::Temporary(vec) => {
80014
                let symbol = vec
80014
                    .get(symbol_id as usize)
80014
                    .ok_or(Error::UnknownSymbol(symbol_id))?;
80014
                match symbol {
80001
                    SymbolStr::Data(symbol) => visitor.visit_borrowed_str(symbol),
13
                    SymbolStr::InList(symbol) => visitor.visit_str(symbol),
                }
            }
40
            SymbolMapRefPrivate::Persistent(vec) => {
40
                let symbol = vec
40
                    .get(symbol_id as usize)
40
                    .ok_or(Error::UnknownSymbol(symbol_id))?;
40
                visitor.visit_str(&symbol)
            }
        }
80054
    }

            
59
    fn push(&mut self, symbol: &str) {
59
        #[allow(clippy::match_same_arms)] // false positive due to lifetimes
59
        match &mut self.0 {
46
            SymbolMapRefPrivate::Temporary(vec) => vec.push(symbol),
13
            SymbolMapRefPrivate::Persistent(vec) => vec.push(symbol),
        }
59
    }

            
239
    fn push_borrowed(&mut self, symbol: &'de str) {
239
        match &mut self.0 {
192
            SymbolMapRefPrivate::Temporary(vec) => vec.push_borrowed(symbol),
47
            SymbolMapRefPrivate::Persistent(vec) => vec.push(symbol),
        }
239
    }
}

            
/// A collection of symbols accumulated during deserialization.
1425
#[derive(Debug)]
pub struct SymbolList<'de> {
    buffer: String,
    entries: Vec<SymbolListEntry<'de>>,
}

            
impl Default for SymbolList<'_> {
    #[inline]
3
    fn default() -> Self {
3
        Self::new()
3
    }
}

            
impl<'de> SymbolList<'de> {
    /// Returns a new, empty symbol list.
    #[inline]
    #[must_use]
215
    pub const fn new() -> Self {
215
        Self {
215
            buffer: String::new(),
215
            entries: Vec::new(),
215
        }
215
    }

            
    /// Push a symbol that has been borrowed from the deserialization source.
    #[inline]
192
    pub fn push_borrowed(&mut self, borrowed: &'de str) {
192
        self.entries.push(SymbolListEntry::Borrowed(borrowed));
192
    }

            
    /// Push a symbol that cannot be borrowed from the deserialization source.
    #[inline]
110
    pub fn push(&mut self, ephemeral: &str) {
110
        let start = self.buffer.len();
110
        self.buffer.push_str(ephemeral);
110
        self.entries
110
            .push(SymbolListEntry::Buffer(start..self.buffer.len()));
110
    }

            
    #[inline]
80056
    fn resolve_entry(&self, entry: &SymbolListEntry<'de>) -> SymbolStr<'de, '_> {
80056
        match entry {
55
            SymbolListEntry::Buffer(range) => SymbolStr::InList(&self.buffer[range.clone()]),
80001
            SymbolListEntry::Borrowed(str) => SymbolStr::Data(str),
        }
80056
    }

            
    /// Return the symbol stored at `index`, or `None` if `index` is out of
    /// bounds.
    #[inline]
    #[must_use]
80054
    pub fn get(&self, index: usize) -> Option<SymbolStr<'de, '_>> {
80054
        self.entries
80054
            .get(index)
80054
            .map(|entry| self.resolve_entry(entry))
80054
    }

            
    /// Returns the number of entries in the symbol list.
    #[inline]
    #[must_use]
7
    pub fn len(&self) -> usize {
7
        self.entries.len()
7
    }

            
    /// Returns true if there are no symbols in this list.
    #[inline]
    #[must_use]
1
    pub fn is_empty(&self) -> bool {
1
        self.len() == 0
1
    }
}

            
/// An alias to a [`SymbolList`] with a static lifetime. This type persists
/// symbols referenced across multiple deserialization sessions.
pub type SymbolMap = SymbolList<'static>;

            
impl SymbolMap {
    /// Returns a deserializer for `slice` that reuses symbol ids.
    ///
    /// This should only be used with data generated by using a persistent
    /// [`ser::SymbolMap`](crate::ser::SymbolMap).
    #[inline]
8
    pub fn deserializer_for_slice<'a, 'de>(
8
        &'a mut self,
8
        slice: &'de [u8],
8
    ) -> Result<Deserializer<'a, 'de, SliceReader<'de>>> {
8
        Deserializer::from_slice_with_symbols(slice, self.persistent(), usize::MAX)
8
    }

            
    /// Returns a deserializer for `reader`.
    ///
    /// This should only be used with data generated by using a persistent
    /// [`ser::SymbolMap`](crate::ser::SymbolMap).
    #[inline]
2
    pub fn deserializer_for<'de, R>(
2
        &mut self,
2
        reader: R,
2
    ) -> Result<Deserializer<'_, 'de, IoReader<R>>>
2
    where
2
        R: Read,
2
    {
2
        Deserializer::from_read(reader, self.persistent(), usize::MAX)
2
    }

            
    /// Deserializes `T` from `slice`.
    ///
    /// This should only be used with data generated by using a persistent
    /// [`ser::SymbolMap`](crate::ser::SymbolMap).
8
    pub fn deserialize_slice<'de, T>(&mut self, slice: &'de [u8]) -> Result<T>
8
    where
8
        T: Deserialize<'de>,
8
    {
8
        T::deserialize(&mut self.deserializer_for_slice(slice)?)
8
    }

            
    /// Deserializes `T` from `reader`.
    ///
    /// This should only be used with data generated by using a persistent
    /// [`ser::SymbolMap`](crate::ser::SymbolMap).
2
    pub fn deserialize_from<'de, T>(&mut self, reader: impl Read) -> Result<T>
2
    where
2
        T: Deserialize<'de>,
2
    {
2
        T::deserialize(&mut self.deserializer_for(reader)?)
2
    }

            
    #[must_use]
19
    fn persistent<'de>(&mut self) -> SymbolMapRef<'_, 'de> {
19
        SymbolMapRef(SymbolMapRefPrivate::Persistent(self))
19
    }
}

            
impl Serialize for SymbolMap {
1
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
1
    where
1
        S: serde::Serializer,
1
    {
1
        let mut seq = serializer.serialize_seq(Some(self.len()))?;
3
        for entry in &self.entries {
2
            seq.serialize_element(&*self.resolve_entry(entry))?;
        }
1
        seq.end()
1
    }
}

            
impl<'de> Deserialize<'de> for SymbolMap {
2
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
2
    where
2
        D: serde::Deserializer<'de>,
2
    {
2
        deserializer.deserialize_seq(SymbolMapVisitor)
2
    }
}

            
struct SymbolMapVisitor;

            
impl<'de> Visitor<'de> for SymbolMapVisitor {
    type Value = SymbolMap;

            
    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        formatter.write_str("symbol map")
    }

            
2
    fn visit_seq<A>(self, mut seq: A) -> std::result::Result<Self::Value, A::Error>
2
    where
2
        A: SeqAccess<'de>,
2
    {
2
        let mut map = SymbolMap::new();
2
        if let Some(hint) = seq.size_hint() {
2
            map.entries.reserve(hint);
2
        }
6
        while let Some(element) = seq.next_element::<Cow<'_, str>>()? {
4
            map.push(&element);
4
        }
2
        Ok(map)
2
    }
}

            
/// A symbol stored in a [`SymbolList`].
pub enum SymbolStr<'de, 'ephemeral> {
    /// A symbol that has been borrowed from the data being deserialized.
    Data(&'de str),
    /// A symbol that is stored inside of the [`SymbolList`].
    InList(&'ephemeral str),
}

            
impl Deref for SymbolStr<'_, '_> {
    type Target = str;

            
    #[inline]
42
    fn deref(&self) -> &Self::Target {
42
        match self {
42
            SymbolStr::Data(str) | SymbolStr::InList(str) => str,
42
        }
42
    }
}

            
8200
#[derive(Debug, Clone)]
enum SymbolListEntry<'de> {
    Buffer(Range<usize>),
    Borrowed(&'de str),
}