fastnbt/
de.rs

1//! This module contains a serde deserializer. It can do most of the things you
2//! would expect of a typical serde deserializer, such as deserializing into:
3//! * Rust structs.
4//! * containers like `HashMap` and `Vec`.
5//! * an arbitrary [`Value`][`crate::Value`].
6//! * enums. For NBT typically you want either internally or untagged enums.
7//!
8//! This deserializer supports [`from_bytes`][`crate::from_bytes`] for zero-copy
9//! deserialization for types like `&[u8]` and
10//! [`borrow::LongArray`][`crate::borrow::LongArray`]. There is also
11//! [`from_reader`][`crate::from_reader`] for deserializing from types
12//! implementing [`Read`][`std::io::Read`].
13//!
14//! # Avoiding allocations
15//!
16//! When using [`from_bytes`][`crate::from_bytes`], we can avoid allocations for
17//! things like strings and vectors, instead deserializing into a reference to
18//! the input data.
19//!
20//! The following table summarises what types you likely want to store NBT data
21//! in for owned or borrowed types:
22//!
23//! | NBT type | Owned type | Borrowed type |
24//! | -------- | ---------- | ------------- |
25//! | Byte | `u8` or `i8` | use owned |
26//! | Short | `u16` or `i16` | use owned |
27//! | Int | `i32` or `u32` | use owned |
28//! | Long | `i64` or `u64` | use owned |
29//! | Float | `f32` | use owned |
30//! | Double | `f64` | use owned |
31//! | String | `String` | [`Cow<'a, str>`][`std::borrow::Cow`] or `&[u8]` (see below) |
32//! | List | `Vec<T>` | use owned |
33//! | Byte Array | [`ByteArray`][`crate::ByteArray`] | [`borrow::ByteArray`][`crate::borrow::ByteArray`] |
34//! | Int Array | [`IntArray`][`crate::IntArray`] | [`borrow::IntArray`][`crate::borrow::IntArray`] |
35//! | Long Array | [`LongArray`][`crate::LongArray`] | [`borrow::LongArray`][`crate::borrow::LongArray`] |
36//!
37//! ## Primitives
38//!
39//! Borrowing for primitive types like the integers and floats is generally not
40//! possible due to alignment requirements of those types. It likely wouldn't be
41//! faster/smaller anyway.
42//!
43//! ## Strings
44//!
45//! For strings, we cannot know ahead of time whether the data can be borrowed
46//! as `&str`. This is because Minecraft uses Java's encoding of Unicode, not
47//! UTF-8. If the string contains Unicode characters outside of the Basic
48//! Multilingual Plane then we need to convert it to UTF-8, requiring us to own
49//! the string data.
50//!
51//! Using [`Cow<'a, str>`][`std::borrow::Cow`] lets us borrow when possible, but
52//! produce an owned value when the representation is different.
53//!
54//! Strings can also be deserialized to `&[u8]` which will always succeed. These
55//! bytes will be Java's CESU-8 format. You can use [`cesu8::from_java_cesu8`]
56//! to decode this.
57//!
58//! # Representation of NBT arrays
59//!
60//! In order for [`Value`][`crate::Value`] to preserve all NBT information, the
61//! deserializer "[maps into serde's data
62//! model](https://serde.rs/data-model.html#mapping-into-the-data-model)". As a
63//! consequence of this, NBT array types must be (de)serialized using the
64//! types provided in this crate, eg [LongArray][`crate::LongArray`]. Sequence
65//! containers like `Vec` will (de)serialize to NBT Lists, and will fail if an
66//! NBT array is instead expected.
67//!
68//! # 128 bit integers and UUIDs
69//!
70//! UUIDs tend to be stored in NBT using 4-long IntArrays. When deserializing
71//! `i128` or `u128`, IntArray with length 4 are accepted. This is parsed as big
72//! endian i.e. the most significant bit (and int) is first.
73//!
74//! # Other quirks
75//!
76//! Some other quirks which may not be obvious:
77//! * When deserializing to unsigned types such as u32, it will be an error if a
78//!   value is negative to avoid unexpected behaviour with wrap-around. This
79//!   does not apply to deserializing lists of integrals to `u8` slice or
80//!   vectors.
81//! * Any integral value from NBT can be deserialized to bool. Any non-zero
82//!   value becomes `true`. Bear in mind serializing the same type will change
83//!   the NBT structure, likely unintended.
84//! * You can deserialize a field to the unit type `()` or unit struct. This
85//!   ignores the value but ensures that it existed.
86//! * You cannot deserialize into anything other than a `struct` or similar
87//!   container eg `HashMap`. This is due to a misalignment between the NBT
88//!   format and Rust's types. Attempting to will give an error about no root
89//!   compound. This means you can never do `let s: String = from_bytes(...)`.
90//!   Serialization of a struct assumes an empty-named compound.
91//!
92//! # Example Minecraft types
93//!
94//! This section demonstrates writing types for a few real Minecraft structures.
95//!
96//! ## Extracting entities as an enum
97//!
98//! This demonstrates the type that you would need to write in order to extract
99//! some subset of entities. This uses a tagged enum in serde, meaning that it
100//! will look for a certain field in the structure to tell it what enum variant
101//! to deserialize into. We use serde's `other` attribute to not error when an
102//! unknown entity type is found.
103//!
104//! ```rust
105//! use serde::Deserialize;
106//!
107//! #[derive(Deserialize, Debug)]
108//! #[serde(tag = "id")]
109//! enum Entity {
110//!    #[serde(rename = "minecraft:bat")]
111//!    Bat {
112//!        #[serde(rename = "BatFlags")]
113//!        bat_flags: i8,
114//!    },
115//!
116//!    #[serde(rename = "minecraft:creeper")]
117//!    Creeper { ignited: i8 },
118//!
119//!    // Entities we haven't coded end up as just 'unknown'.
120//!    #[serde(other)]
121//!    Unknown,
122//! }
123//! ```
124//!
125//! ## Capture unknown entities
126//!
127//! If you need to capture all entity types, but do not wish to manually type
128//! all of them, you can wrap the above entity type in an untagged enum.
129//!
130//! ```rust
131//! use serde::Deserialize;
132//! use fastnbt::Value;
133//!
134//! #[derive(Deserialize, Debug)]
135//! #[serde(untagged)]
136//! enum Entity {
137//!     Known(KnownEntity),
138//!     Unknown(Value),
139//! }
140
141//! #[derive(Deserialize, Debug)]
142//! #[serde(tag = "id")]
143//! enum KnownEntity {
144//!     #[serde(rename = "minecraft:bat")]
145//!     Bat {
146//!         #[serde(rename = "BatFlags")]
147//!         bat_flags: i8,
148//!     },
149
150//!     #[serde(rename = "minecraft:creeper")]
151//!     Creeper { ignited: i8 },
152//! }
153//! ```
154//!
155//! ## Avoiding allocations in a Chunk
156//!
157//! This example shows how to avoid some allocations. The `Section` type below
158//! contains the block states which stores the state of part of the Minecraft
159//! world. In NBT this is bit-packed data stored as an array of
160//! longs (i64). We avoid allocating a vector for this by storing it as a
161//! [`borrow::LongArray`][`crate::borrow::LongArray`] instead, which stores it
162//! as `&[u8]` under the hood. We can't safely store it as `&[i64]` due to memory
163//! alignment constraints. The `fastanvil` crate has a `PackedBits` type that can
164//! handle the unpacking of these block states.
165//!
166//! ```rust
167//! # use serde::Deserialize;
168//! use fastnbt::borrow::LongArray;
169//!
170//! #[derive(Deserialize)]
171//! struct Chunk<'a> {
172//!     #[serde(rename = "Level")]
173//!     #[serde(borrow)]
174//!     level: Level<'a>,
175//! }
176//!
177//! #[derive(Deserialize)]
178//! struct Level<'a> {
179//!     #[serde(rename = "Sections")]
180//!     #[serde(borrow)]
181//!     pub sections: Option<Vec<Section<'a>>>,
182//! }
183//!
184//! #[derive(Deserialize, Debug)]
185//! #[serde(rename_all = "PascalCase")]
186//! pub struct Section<'a> {
187//!     #[serde(borrow)]
188//!     pub block_states: Option<LongArray<'a>>,
189//! }
190//! ```
191//!
192//! ## Unit variant enum from status of chunk
193//!
194//! ```no_run
195//! use serde::Deserialize;
196//!
197//! #[derive(Deserialize)]
198//! struct Chunk {
199//!     #[serde(rename = "Level")]
200//!     level: Level,
201//! }
202//!
203//! #[derive(Deserialize)]
204//! struct Level {
205//!     #[serde(rename = "Status")]
206//!     status: Status,
207//! }
208//!
209//! #[derive(Deserialize, PartialEq, Debug)]
210//! #[serde(rename_all = "snake_case")]
211//! enum Status {
212//!     Empty,
213//!     StructureStarts,
214//!     StructureReferences,
215//!     Biomes,
216//!     Noise,
217//!     Surface,
218//!     Carvers,
219//!     LiquidCarvers,
220//!     Features,
221//!     Light,
222//!     Spawn,
223//!     Heightmaps,
224//!     Full,
225//! }
226//! ```
227use std::io::Read;
228
229use serde::{
230    de::{
231        self,
232        value::{BorrowedBytesDeserializer, BorrowedStrDeserializer, BytesDeserializer},
233    },
234    forward_to_deserialize_any,
235};
236
237use crate::{
238    error::{Error, Result},
239    input, DeOpts, Tag, BYTE_ARRAY_TOKEN, INT_ARRAY_TOKEN, LONG_ARRAY_TOKEN,
240};
241
242use crate::input::{Input, Reference};
243
244/// Deserializer for NBT data. See the [`de`] module for more information.
245///
246/// [`de`]: ./index.html
247pub struct Deserializer<In> {
248    input: In,
249    scratch: Vec<u8>,
250    seen_root: bool,
251    opts: DeOpts,
252}
253
254impl<'de, In> Deserializer<In>
255where
256    In: Input<'de>,
257{
258    pub fn new(input: In, opts: DeOpts) -> Self {
259        Self {
260            input,
261            scratch: Vec::new(),
262            seen_root: false,
263            opts,
264        }
265    }
266}
267
268impl<'a> Deserializer<input::Slice<'a>> {
269    /// Create Deserializer for a `T` from some NBT data slice. See the [`de`] module
270    /// for more information.
271    ///
272    /// [`de`]: ./index.html
273    pub fn from_bytes(bytes: &'a [u8], opts: DeOpts) -> Self {
274        Deserializer::new(input::Slice { data: bytes }, opts)
275    }
276}
277
278impl<R: Read> Deserializer<input::Reader<R>> {
279    /// Create Deserializer for a `T` from some NBT data. See the [`de`] module
280    /// for more information.
281    ///
282    /// [`de`]: ./index.html
283    pub fn from_reader(reader: R, opts: DeOpts) -> Self {
284        Deserializer::new(input::Reader { reader }, opts)
285    }
286}
287
288impl<'de, 'a, In> de::Deserializer<'de> for &'a mut Deserializer<In>
289where
290    In: Input<'de>,
291{
292    type Error = Error;
293
294    forward_to_deserialize_any! {
295        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit unit_struct seq tuple tuple_struct
296        identifier ignored_any bytes enum newtype_struct byte_buf option
297    }
298
299    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
300    where
301        V: de::Visitor<'de>,
302    {
303        self.deserialize_map(visitor)
304    }
305
306    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
307    where
308        V: de::Visitor<'de>,
309    {
310        if !self.seen_root {
311            let peek = self.input.consume_tag()?;
312
313            match peek {
314                Tag::Compound => {
315                    if self.opts.expect_coumpound_names {
316                        self.input.ignore_str()?
317                    }
318                }
319                _ => return Err(Error::no_root_compound()),
320            }
321
322            self.seen_root = true;
323        }
324
325        visitor.visit_map(MapAccess::new(self))
326    }
327
328    fn deserialize_struct<V>(
329        self,
330        _name: &'static str,
331        _fields: &'static [&'static str],
332        visitor: V,
333    ) -> Result<V::Value>
334    where
335        V: de::Visitor<'de>,
336    {
337        self.deserialize_map(visitor)
338    }
339}
340
341struct MapAccess<'a, In: 'a> {
342    de: &'a mut Deserializer<In>,
343    tag: Tag, // current tag
344}
345
346impl<'a, In: 'a> MapAccess<'a, In> {
347    pub fn new(de: &'a mut Deserializer<In>) -> Self {
348        Self { de, tag: Tag::End }
349    }
350}
351
352impl<'de, 'a, In: Input<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, In> {
353    type Error = Error;
354
355    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
356    where
357        K: de::DeserializeSeed<'de>,
358    {
359        self.tag = self.de.input.consume_tag()?;
360        if self.tag == Tag::End {
361            return Ok(None);
362        }
363
364        seed.deserialize(MapKey { de: &mut *self.de }).map(Some)
365    }
366
367    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
368    where
369        V: de::DeserializeSeed<'de>,
370    {
371        seed.deserialize(AnonymousValue {
372            tag: self.tag,
373            de: &mut *self.de,
374            last_hint: Hint::None,
375        })
376    }
377}
378
379struct MapKey<'a, In> {
380    de: &'a mut Deserializer<In>,
381}
382
383fn arr_check(key: &str) -> Result<&str> {
384    if key.starts_with("__")
385        && (key == BYTE_ARRAY_TOKEN || key == INT_ARRAY_TOKEN || key == LONG_ARRAY_TOKEN)
386    {
387        Err(Error::bespoke(
388            "compound using special fastnbt array tokens".to_string(),
389        ))
390    } else {
391        Ok(key)
392    }
393}
394
395impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R>
396where
397    R: Input<'de>,
398{
399    type Error = Error;
400
401    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
402    where
403        V: de::Visitor<'de>,
404    {
405        match self.de.input.consume_str(&mut self.de.scratch)? {
406            Reference::Borrowed(s) => visitor.visit_borrowed_str(arr_check(s)?),
407            Reference::Copied(s) => visitor.visit_str(arr_check(s)?),
408        }
409    }
410
411    forward_to_deserialize_any! {
412        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit unit_struct seq tuple tuple_struct map
413        struct identifier ignored_any bytes enum newtype_struct byte_buf option
414    }
415}
416
417enum Hint {
418    None,
419    Seq,
420}
421
422/// Deserializer for an anonymous value, ie one with no tag or name before it.
423/// This occurs in lists, but is also used to deserialize the value part of compounds.
424///
425/// This is the 'core' of the deserializer if there can be said to be one.
426struct AnonymousValue<'a, In> {
427    tag: Tag,
428    last_hint: Hint,
429    de: &'a mut Deserializer<In>,
430}
431
432impl<'de, 'a, In> de::Deserializer<'de> for AnonymousValue<'a, In>
433where
434    In: Input<'de>,
435{
436    type Error = Error;
437
438    forward_to_deserialize_any!(u8 u16 u32 u64 i8 i16 i32 i64 f32
439        f64 str string struct tuple map identifier char);
440
441    fn deserialize_any<V>(mut self, v: V) -> Result<V::Value>
442    where
443        V: de::Visitor<'de>,
444    {
445        let last_hint = self.last_hint;
446        self.last_hint = Hint::None;
447
448        match self.tag {
449            Tag::End => Err(Error::bespoke("expected value, found end tag".into())),
450            Tag::Byte => v.visit_i8(self.de.input.consume_byte()? as i8),
451            Tag::Short => v.visit_i16(self.de.input.consume_i16()?),
452            Tag::Int => v.visit_i32(self.de.input.consume_i32()?),
453            Tag::Long => v.visit_i64(self.de.input.consume_i64()?),
454            Tag::Float => v.visit_f32(self.de.input.consume_f32()?),
455            Tag::Double => v.visit_f64(self.de.input.consume_f64()?),
456            Tag::String => match self.de.input.consume_str(&mut self.de.scratch)? {
457                Reference::Borrowed(s) => v.visit_borrowed_str(s),
458                Reference::Copied(s) => v.visit_str(s),
459            },
460            Tag::List => {
461                let tag = self.de.input.consume_tag()?;
462                let remaining = self.de.input.consume_i32()? as usize;
463
464                // End values have no payload. An end tag on it's own is the payload
465                // of an empty compound. A logical interpretation is that this could
466                // be a list of zero-sized units, but this mean an easy short
467                // malicious payload of a massive list taking up lots of memory (as
468                // the Value type's unit variant would not be zero sized.
469                //
470                // Some old chunks store empty lists as as 'list of end', so if the
471                // size is zero we let it slide.
472                if tag == Tag::End && remaining != 0 {
473                    return Err(Error::bespoke(
474                        "unexpected list of type 'end', which is not supported".into(),
475                    ));
476                }
477
478                if remaining > self.de.opts.max_seq_len {
479                    return Err(Error::bespoke(format!(
480                        "size ({}) greater than max sequence length ({})",
481                        remaining, self.de.opts.max_seq_len,
482                    )));
483                }
484
485                v.visit_seq(ListAccess {
486                    de: self.de,
487                    tag,
488                    remaining,
489                })
490            }
491            Tag::Compound => v.visit_map(MapAccess::new(self.de)),
492            Tag::ByteArray => {
493                if let Hint::Seq = last_hint {
494                    return Err(Error::array_as_seq());
495                }
496                let len = self.de.input.consume_i32()? as usize;
497                v.visit_map(ArrayWrapperAccess::bytes(self.de, len)?)
498            }
499            Tag::IntArray => {
500                if let Hint::Seq = last_hint {
501                    return Err(Error::array_as_seq());
502                }
503                let len = self.de.input.consume_i32()? as usize;
504                v.visit_map(ArrayWrapperAccess::ints(self.de, len)?)
505            }
506            Tag::LongArray => {
507                if let Hint::Seq = last_hint {
508                    return Err(Error::array_as_seq());
509                }
510                let len = self.de.input.consume_i32()? as usize;
511                v.visit_map(ArrayWrapperAccess::longs(self.de, len)?)
512            }
513        }
514    }
515
516    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
517    where
518        V: de::Visitor<'de>,
519    {
520        let consume_visit =
521            |de: &mut Deserializer<In>, len: usize, el_size| match de.input.consume_bytes(
522                len.checked_mul(el_size)
523                    .ok_or_else(|| Error::bespoke("overflow deserializing bytes".to_string()))?,
524                &mut de.scratch,
525            )? {
526                Reference::Borrowed(bs) => visitor.visit_borrowed_bytes(bs),
527                Reference::Copied(bs) => visitor.visit_bytes(bs),
528            };
529
530        match self.tag {
531            Tag::String => {
532                let len = self.de.input.consume_i16()? as usize;
533                consume_visit(self.de, len, 1)
534            }
535            Tag::List => {
536                let tag = self.de.input.consume_tag()?;
537                let remaining = self.de.input.consume_i32()? as usize;
538
539                match tag {
540                    Tag::Byte => consume_visit(self.de, remaining, std::mem::size_of::<i8>()),
541                    Tag::Short => consume_visit(self.de, remaining, std::mem::size_of::<i16>()),
542                    Tag::Int => consume_visit(self.de, remaining, std::mem::size_of::<i32>()),
543                    Tag::Long => consume_visit(self.de, remaining, std::mem::size_of::<i64>()),
544                    _ => Err(Error::bespoke(format!(
545                        "cannot convert list of {} to bytes",
546                        tag
547                    ))),
548                }
549            }
550            Tag::ByteArray => {
551                let remaining = self.de.input.consume_i32()? as usize;
552                consume_visit(self.de, remaining, std::mem::size_of::<i8>())
553            }
554            Tag::LongArray => {
555                let remaining = self.de.input.consume_i32()? as usize;
556                consume_visit(self.de, remaining, std::mem::size_of::<i64>())
557            }
558            _ => Err(Error::bespoke(format!(
559                "cannot convert {} to bytes",
560                self.tag
561            ))),
562        }
563    }
564
565    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
566    where
567        V: de::Visitor<'de>,
568    {
569        self.deserialize_bytes(visitor)
570    }
571
572    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
573    where
574        V: de::Visitor<'de>,
575    {
576        visitor.visit_some(self)
577    }
578
579    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
580    where
581        V: de::Visitor<'de>,
582    {
583        // fastnbt quirk: if your type contains a unit, we allow any valid NBT
584        // value to 'fill' that hole in your type. This means a unit type can be
585        // used to ensure the presense of a value in the NBT without actually
586        // caring or deserializing its contents.
587        self.de.input.ignore_value(self.tag)?;
588        visitor.visit_unit()
589    }
590
591    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
592    where
593        V: de::Visitor<'de>,
594    {
595        self.deserialize_unit(visitor)
596    }
597
598    fn deserialize_tuple_struct<V>(
599        self,
600        _name: &'static str,
601        _len: usize,
602        visitor: V,
603    ) -> Result<V::Value>
604    where
605        V: de::Visitor<'de>,
606    {
607        self.deserialize_seq(visitor)
608    }
609
610    fn deserialize_enum<V>(
611        self,
612        _name: &'static str,
613        _variants: &'static [&'static str],
614        visitor: V,
615    ) -> Result<V::Value>
616    where
617        V: de::Visitor<'de>,
618    {
619        visitor.visit_enum(UnitVariantAccess {
620            de: AnonymousValue {
621                tag: self.tag,
622                de: self.de,
623                last_hint: Hint::None,
624            },
625        })
626    }
627
628    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
629    where
630        V: de::Visitor<'de>,
631    {
632        self.de.input.ignore_value(self.tag)?;
633        visitor.visit_unit()
634    }
635
636    fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
637    where
638        V: de::Visitor<'de>,
639    {
640        self.last_hint = Hint::Seq;
641        self.deserialize_any(visitor)
642    }
643
644    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
645    where
646        V: de::Visitor<'de>,
647    {
648        // We specifically allow any intergral type to be deserialized into a
649        // bool.
650        match self.tag {
651            Tag::Byte => visitor.visit_bool(self.de.input.consume_byte()? != 0),
652            Tag::Short => visitor.visit_bool(self.de.input.consume_i16()? != 0),
653            Tag::Int => visitor.visit_bool(self.de.input.consume_i32()? != 0),
654            Tag::Long => visitor.visit_bool(self.de.input.consume_i64()? != 0),
655            _ => self.deserialize_any(visitor),
656        }
657    }
658
659    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
660    where
661        V: de::Visitor<'de>,
662    {
663        visitor.visit_newtype_struct(self)
664    }
665
666    #[inline]
667    fn deserialize_i128<V>(mut self, visitor: V) -> Result<V::Value>
668    where
669        V: de::Visitor<'de>,
670    {
671        visitor.visit_i128(get_i128_value(&mut self)?)
672    }
673
674    #[inline]
675    fn deserialize_u128<V>(mut self, visitor: V) -> Result<V::Value>
676    where
677        V: de::Visitor<'de>,
678    {
679        visitor.visit_u128(get_i128_value(&mut self)? as u128)
680    }
681}
682
683struct ListAccess<'a, In: 'a> {
684    de: &'a mut Deserializer<In>,
685    tag: Tag, // current tag
686    remaining: usize,
687}
688
689impl<'de, 'a, In: Input<'de> + 'a> de::SeqAccess<'de> for ListAccess<'a, In> {
690    type Error = Error;
691
692    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
693    where
694        T: de::DeserializeSeed<'de>,
695    {
696        if self.remaining > 0 {
697            self.remaining -= 1;
698            seed.deserialize(AnonymousValue {
699                de: &mut *self.de,
700                last_hint: Hint::None,
701                tag: self.tag,
702            })
703            .map(Some)
704        } else {
705            Ok(None)
706        }
707    }
708}
709
710struct UnitVariantAccess<'a, In: 'a> {
711    de: AnonymousValue<'a, In>,
712}
713
714impl<'de, 'a, In: Input<'de> + 'a> de::EnumAccess<'de> for UnitVariantAccess<'a, In> {
715    type Error = Error;
716    type Variant = Self;
717
718    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
719    where
720        V: serde::de::DeserializeSeed<'de>,
721    {
722        let variant = seed.deserialize(AnonymousValue {
723            de: &mut *self.de.de,
724            last_hint: Hint::None,
725            tag: self.de.tag,
726        })?;
727        Ok((variant, self))
728    }
729}
730
731impl<'de, 'a, In: Input<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, In> {
732    type Error = Error;
733
734    fn unit_variant(self) -> Result<()> {
735        Ok(())
736    }
737
738    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
739    where
740        T: serde::de::DeserializeSeed<'de>,
741    {
742        Err(de::Error::invalid_type(
743            de::Unexpected::UnitVariant,
744            &"newtype variant",
745        ))
746    }
747
748    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
749    where
750        V: de::Visitor<'de>,
751    {
752        Err(de::Error::invalid_type(
753            de::Unexpected::TupleVariant,
754            &"tuple variant",
755        ))
756    }
757
758    fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
759    where
760        V: de::Visitor<'de>,
761    {
762        Err(de::Error::invalid_type(
763            de::Unexpected::StructVariant,
764            &"struct variant",
765        ))
766    }
767}
768
769enum State {
770    Unread,
771    Read,
772}
773
774pub(crate) struct ArrayWrapperAccess<'a, In: 'a> {
775    de: &'a mut Deserializer<In>,
776    token: &'static str,
777    bytes_size: usize,
778    state: State,
779}
780
781impl<'a, In: 'a> ArrayWrapperAccess<'a, In> {
782    pub(crate) fn bytes(de: &'a mut Deserializer<In>, size: usize) -> Result<Self> {
783        Ok(Self {
784            de,
785            bytes_size: size
786                .checked_mul(1)
787                .ok_or_else(|| Error::bespoke("nbt array too large".to_string()))?,
788            token: BYTE_ARRAY_TOKEN,
789            state: State::Unread,
790        })
791    }
792
793    pub(crate) fn ints(de: &'a mut Deserializer<In>, size: usize) -> Result<Self> {
794        Ok(Self {
795            de,
796            bytes_size: size
797                .checked_mul(4)
798                .ok_or_else(|| Error::bespoke("nbt array too large".to_string()))?,
799            token: INT_ARRAY_TOKEN,
800            state: State::Unread,
801        })
802    }
803
804    pub(crate) fn longs(de: &'a mut Deserializer<In>, size: usize) -> Result<Self> {
805        Ok(Self {
806            de,
807            bytes_size: size
808                .checked_mul(8)
809                .ok_or_else(|| Error::bespoke("nbt array too large".to_string()))?,
810            token: LONG_ARRAY_TOKEN,
811            state: State::Unread,
812        })
813    }
814}
815
816impl<'de, 'a, In: Input<'de> + 'a> de::MapAccess<'de> for ArrayWrapperAccess<'a, In> {
817    type Error = Error;
818
819    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
820    where
821        K: de::DeserializeSeed<'de>,
822    {
823        if let State::Unread = self.state {
824            self.state = State::Read;
825            seed.deserialize(BorrowedStrDeserializer::new(self.token))
826                .map(Some)
827        } else {
828            Ok(None)
829        }
830    }
831
832    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
833    where
834        V: de::DeserializeSeed<'de>,
835    {
836        let data = self
837            .de
838            .input
839            .consume_bytes(self.bytes_size, &mut self.de.scratch)?;
840
841        match data {
842            Reference::Borrowed(bs) => seed.deserialize(BorrowedBytesDeserializer::new(bs)),
843            Reference::Copied(bs) => seed.deserialize(BytesDeserializer::new(bs)),
844        }
845    }
846}
847
848fn get_i128_value<'de, In>(de: &mut AnonymousValue<In>) -> Result<i128>
849where
850    In: Input<'de>,
851{
852    let tag = de.tag;
853
854    match tag {
855        Tag::IntArray => {
856            let size = de.de.input.consume_i32()? as usize;
857
858            let size = size
859                .checked_mul(4)
860                .ok_or_else(|| Error::bespoke("nbt array too large".to_string()))?;
861
862            let bs = de.de.input.consume_bytes(size, &mut de.de.scratch)?;
863            let bs = bs.as_ref();
864
865            match bs.try_into() {
866                Ok(bs) => Ok(i128::from_be_bytes(bs)),
867                Err(_) => Err(Error::bespoke(format!(
868                    "deserialize i128: expected IntArray of length 4 with 16 bytes, found {} bytes",
869                    bs.len()
870                ))),
871            }
872        }
873        _ => Err(Error::bespoke(
874            "deserialize i128: expected IntArray value".to_string(),
875        )),
876    }
877}