nbt/
ser.rs

1//! Serialize a Rust data structure into Named Binary Tag data.
2
3use std::io;
4
5use flate2::write::{GzEncoder, ZlibEncoder};
6use flate2::Compression;
7use serde;
8use serde::ser;
9
10use raw;
11
12use error::{Error, Result};
13use serde::ser::Error as SerError;
14
15/// Encode `value` in Named Binary Tag format to the given `io::Write`
16/// destination, with an optional header.
17#[inline]
18pub fn to_writer<'a, W, T>(dst: &mut W, value: &T, header: Option<&'a str>) -> Result<()>
19where
20    W: ?Sized + io::Write,
21    T: ?Sized + ser::Serialize,
22{
23    let mut encoder = Encoder::new(dst, header);
24    value.serialize(&mut encoder)
25}
26
27/// Encode `value` in Named Binary Tag format to the given `io::Write`
28/// destination, with an optional header.
29pub fn to_gzip_writer<'a, W, T>(dst: &mut W, value: &T, header: Option<&'a str>) -> Result<()>
30where
31    W: ?Sized + io::Write,
32    T: ?Sized + ser::Serialize,
33{
34    let mut encoder = Encoder::new(GzEncoder::new(dst, Compression::default()), header);
35    value.serialize(&mut encoder)
36}
37
38/// Encode `value` in Named Binary Tag format to the given `io::Write`
39/// destination, with an optional header.
40pub fn to_zlib_writer<'a, W, T>(dst: &mut W, value: &T, header: Option<&'a str>) -> Result<()>
41where
42    W: ?Sized + io::Write,
43    T: ?Sized + ser::Serialize,
44{
45    let mut encoder = Encoder::new(ZlibEncoder::new(dst, Compression::default()), header);
46    value.serialize(&mut encoder)
47}
48
49/// Encode objects to Named Binary Tag format.
50///
51/// This structure can be used to serialize objects which implement the
52/// `serde::Serialize` trait into NBT format. Note that not all types are
53/// representable in NBT format (notably unsigned integers), so this encoder may
54/// return errors.
55pub struct Encoder<'a, W> {
56    writer: W,
57    header: Option<&'a str>,
58}
59
60impl<'a, W> Encoder<'a, W>
61where
62    W: io::Write,
63{
64    /// Create an encoder with optional `header` from a given Writer.
65    pub fn new(writer: W, header: Option<&'a str>) -> Self {
66        Encoder { writer, header }
67    }
68
69    /// Write the NBT tag and an optional header to the underlying writer.
70    #[inline]
71    fn write_header(&mut self, tag: i8, header: Option<&str>) -> Result<()> {
72        raw::write_bare_byte(&mut self.writer, tag)?;
73        match header {
74            None => raw::write_bare_short(&mut self.writer, 0).map_err(From::from),
75            Some(h) => raw::write_bare_string(&mut self.writer, h).map_err(From::from),
76        }
77    }
78}
79
80/// "Inner" version of the NBT encoder, capable of serializing bare types.
81struct InnerEncoder<'a, 'b: 'a, W: 'a> {
82    outer: &'a mut Encoder<'b, W>,
83}
84
85impl<'a, 'b, W> InnerEncoder<'a, 'b, W>
86where
87    W: io::Write,
88{
89    pub fn from_outer(outer: &'a mut Encoder<'b, W>) -> Self {
90        InnerEncoder { outer }
91    }
92}
93
94#[doc(hidden)]
95pub struct Compound<'a, 'b: 'a, W: 'a> {
96    outer: &'a mut Encoder<'b, W>,
97    length: i32,
98    sigil: bool,
99}
100
101impl<'a, 'b, W> Compound<'a, 'b, W>
102where
103    W: io::Write,
104{
105    fn from_outer(outer: &'a mut Encoder<'b, W>) -> Self {
106        Compound {
107            outer,
108            length: 0,
109            sigil: false,
110        }
111    }
112
113    fn for_seq(outer: &'a mut Encoder<'b, W>, length: i32, array: bool) -> Result<Self> {
114        if length == 0 || array {
115            // Write sigil for empty list or typed array, because SerializeSeq::serialize_element is never called
116            if !array {
117                // For an empty list, write TAG_End as the tag type.
118                raw::write_bare_byte(&mut outer.writer, 0x00)?;
119            }
120            // Write list/array length
121            raw::write_bare_int(&mut outer.writer, length)?;
122        }
123        Ok(Compound {
124            outer,
125            length,
126            sigil: false,
127        })
128    }
129}
130
131impl<'a, 'b, W> ser::SerializeSeq for Compound<'a, 'b, W>
132where
133    W: io::Write,
134{
135    type Ok = ();
136    type Error = Error;
137
138    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
139    where
140        T: serde::Serialize,
141    {
142        if !self.sigil {
143            value.serialize(&mut TagEncoder::from_outer(
144                self.outer,
145                Option::<String>::None,
146            ))?;
147            raw::write_bare_int(&mut self.outer.writer, self.length)?;
148            self.sigil = true;
149        }
150        value.serialize(&mut InnerEncoder::from_outer(self.outer))
151    }
152
153    fn end(self) -> Result<()> {
154        Ok(())
155    }
156}
157
158impl<'a, 'b, W> ser::SerializeTupleStruct for Compound<'a, 'b, W>
159where
160    W: io::Write,
161{
162    type Ok = ();
163    type Error = Error;
164
165    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
166    where
167        T: serde::Serialize,
168    {
169        value.serialize(&mut InnerEncoder::from_outer(self.outer))
170    }
171
172    fn end(self) -> Result<()> {
173        Ok(())
174    }
175}
176
177impl<'a, 'b, W> ser::SerializeStruct for Compound<'a, 'b, W>
178where
179    W: io::Write,
180{
181    type Ok = ();
182    type Error = Error;
183
184    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
185    where
186        T: serde::Serialize,
187    {
188        value.serialize(&mut TagEncoder::from_outer(self.outer, Some(key)))?;
189        value.serialize(&mut InnerEncoder::from_outer(self.outer))
190    }
191
192    fn end(self) -> Result<()> {
193        raw::close_nbt(&mut self.outer.writer)
194    }
195}
196
197impl<'a, 'b, W> ser::SerializeMap for Compound<'a, 'b, W>
198where
199    W: io::Write,
200{
201    type Ok = ();
202    type Error = Error;
203
204    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
205    where
206        T: serde::Serialize,
207    {
208        unimplemented!()
209    }
210
211    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
212    where
213        T: serde::Serialize,
214    {
215        unimplemented!()
216    }
217
218    fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>
219    where
220        K: serde::Serialize,
221        V: serde::Serialize,
222    {
223        value.serialize(&mut TagEncoder::from_outer(self.outer, Some(key)))?;
224        value.serialize(&mut InnerEncoder::from_outer(self.outer))
225    }
226
227    fn end(self) -> Result<()> {
228        raw::close_nbt(&mut self.outer.writer)
229    }
230}
231
232impl<'a, 'b, W> serde::Serializer for &'a mut Encoder<'b, W>
233where
234    W: io::Write,
235{
236    type Ok = ();
237    type Error = Error;
238    type SerializeSeq = ser::Impossible<(), Error>;
239    type SerializeTuple = ser::Impossible<(), Error>;
240    type SerializeTupleStruct = ser::Impossible<(), Error>;
241    type SerializeTupleVariant = ser::Impossible<(), Error>;
242    type SerializeMap = Compound<'a, 'b, W>;
243    type SerializeStruct = Compound<'a, 'b, W>;
244    type SerializeStructVariant = ser::Impossible<(), Error>;
245
246    return_expr_for_serialized_types!(
247        Err(Error::NoRootCompound); bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64
248            char str bytes none some unit unit_variant newtype_variant
249            seq tuple tuple_struct tuple_variant struct_variant
250    );
251
252    /// Serialize unit structs as empty `Tag_Compound` data.
253    #[inline]
254    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
255        let header = self.header; // Circumvent strange borrowing errors.
256        self.write_header(0x0a, header)?;
257        raw::close_nbt(&mut self.writer).map_err(From::from)
258    }
259
260    /// Serialize newtype structs by their underlying type. Note that this will
261    /// only be successful if the underyling type is a struct or a map.
262    #[inline]
263    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()>
264    where
265        T: ser::Serialize,
266    {
267        value.serialize(self)
268    }
269
270    /// Serialize maps as `Tag_Compound` data.
271    #[inline]
272    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
273        let header = self.header; // Circumvent strange borrowing errors.
274        self.write_header(0x0a, header)?;
275        Ok(Compound::from_outer(self))
276    }
277
278    /// Serialize structs as `Tag_Compound` data.
279    #[inline]
280    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
281        let header = self.header; // Circumvent strange borrowing errors.
282        self.write_header(0x0a, header)?;
283        Ok(Compound::from_outer(self))
284    }
285}
286
287impl<'a, 'b, W> serde::Serializer for &'a mut InnerEncoder<'a, 'b, W>
288where
289    W: io::Write,
290{
291    type Ok = ();
292    type Error = Error;
293    type SerializeSeq = Compound<'a, 'b, W>;
294    type SerializeTuple = ser::Impossible<(), Error>;
295    type SerializeTupleStruct = Compound<'a, 'b, W>;
296    type SerializeTupleVariant = ser::Impossible<(), Error>;
297    type SerializeMap = Compound<'a, 'b, W>;
298    type SerializeStruct = Compound<'a, 'b, W>;
299    type SerializeStructVariant = ser::Impossible<(), Error>;
300
301    unrepresentable!(
302        u8 u16 u32 u64 char unit newtype_variant tuple
303            tuple_variant struct_variant
304    );
305
306    #[inline]
307    fn serialize_bool(self, value: bool) -> Result<()> {
308        self.serialize_i8(value as i8)
309    }
310
311    #[inline]
312    fn serialize_i8(self, value: i8) -> Result<()> {
313        raw::write_bare_byte(&mut self.outer.writer, value).map_err(From::from)
314    }
315
316    #[inline]
317    fn serialize_i16(self, value: i16) -> Result<()> {
318        raw::write_bare_short(&mut self.outer.writer, value).map_err(From::from)
319    }
320
321    #[inline]
322    fn serialize_i32(self, value: i32) -> Result<()> {
323        raw::write_bare_int(&mut self.outer.writer, value).map_err(From::from)
324    }
325
326    #[inline]
327    fn serialize_i64(self, value: i64) -> Result<()> {
328        raw::write_bare_long(&mut self.outer.writer, value).map_err(From::from)
329    }
330
331    #[inline]
332    fn serialize_f32(self, value: f32) -> Result<()> {
333        raw::write_bare_float(&mut self.outer.writer, value).map_err(From::from)
334    }
335
336    #[inline]
337    fn serialize_f64(self, value: f64) -> Result<()> {
338        raw::write_bare_double(&mut self.outer.writer, value).map_err(From::from)
339    }
340
341    #[inline]
342    fn serialize_str(self, value: &str) -> Result<()> {
343        raw::write_bare_string(&mut self.outer.writer, value).map_err(From::from)
344    }
345
346    #[inline]
347    fn serialize_unit_variant(
348        self,
349        _name: &'static str,
350        _variant_index: u32,
351        variant: &'static str,
352    ) -> Result<()> {
353        self.serialize_str(variant)
354    }
355
356    #[inline]
357    fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
358        Err(Error::UnrepresentableType("u8"))
359    }
360
361    #[inline]
362    fn serialize_none(self) -> Result<()> {
363        Ok(())
364    }
365
366    #[inline]
367    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
368    where
369        T: ser::Serialize,
370    {
371        value.serialize(self)
372    }
373
374    #[inline]
375    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
376        raw::close_nbt(&mut self.outer.writer).map_err(From::from)
377    }
378
379    #[inline]
380    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()>
381    where
382        T: ser::Serialize,
383    {
384        value.serialize(self)
385    }
386
387    #[inline]
388    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
389        if let Some(l) = len {
390            Compound::for_seq(self.outer, l as i32, false)
391        } else {
392            Err(Error::UnrepresentableType("unsized list"))
393        }
394    }
395
396    #[inline]
397    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
398        Ok(Compound::from_outer(self.outer))
399    }
400
401    #[inline]
402    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
403        Ok(Compound::from_outer(self.outer))
404    }
405
406    fn serialize_tuple_struct(
407        self,
408        name: &'static str,
409        len: usize,
410    ) -> Result<Self::SerializeTupleStruct> {
411        match name {
412            "__hematite_nbt_i8_array__"
413            | "__hematite_nbt_i32_array__"
414            | "__hematite_nbt_i64_array__" => Compound::for_seq(self.outer, len as i32, true),
415            _ => Err(Error::UnrepresentableType(stringify!(tuple_struct))),
416        }
417    }
418}
419
420/// A serializer for valid map keys, i.e. strings.
421struct MapKeyEncoder<'a, 'b: 'a, W: 'a> {
422    outer: &'a mut Encoder<'b, W>,
423}
424
425impl<'a, 'b: 'a, W: 'a> MapKeyEncoder<'a, 'b, W>
426where
427    W: io::Write,
428{
429    pub fn from_outer(outer: &'a mut Encoder<'b, W>) -> Self {
430        MapKeyEncoder { outer }
431    }
432}
433
434impl<'a, 'b: 'a, W: 'a> serde::Serializer for &'a mut MapKeyEncoder<'a, 'b, W>
435where
436    W: io::Write,
437{
438    type Ok = ();
439    type Error = Error;
440    type SerializeSeq = ser::Impossible<(), Error>;
441    type SerializeTuple = ser::Impossible<(), Error>;
442    type SerializeTupleStruct = ser::Impossible<(), Error>;
443    type SerializeTupleVariant = ser::Impossible<(), Error>;
444    type SerializeMap = ser::Impossible<(), Error>;
445    type SerializeStruct = ser::Impossible<(), Error>;
446    type SerializeStructVariant = ser::Impossible<(), Error>;
447
448    return_expr_for_serialized_types!(
449        Err(Error::NonStringMapKey); bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64
450            char bytes unit unit_variant newtype_variant unit_struct seq tuple
451            tuple_struct tuple_variant struct_variant newtype_struct map struct
452    );
453
454    fn serialize_none(self) -> Result<()> {
455        Ok(())
456    }
457
458    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
459    where
460        T: ser::Serialize,
461    {
462        value.serialize(self)
463    }
464
465    fn serialize_str(self, value: &str) -> Result<()> {
466        raw::write_bare_string(&mut self.outer.writer, value)
467    }
468}
469
470/// A serializer for valid map keys.
471struct TagEncoder<'a, 'b: 'a, W: 'a, K> {
472    outer: &'a mut Encoder<'b, W>,
473    key: Option<K>,
474}
475
476impl<'a, 'b: 'a, W: 'a, K> TagEncoder<'a, 'b, W, K>
477where
478    W: io::Write,
479    K: serde::Serialize,
480{
481    fn from_outer(outer: &'a mut Encoder<'b, W>, key: Option<K>) -> Self {
482        TagEncoder { outer, key }
483    }
484
485    fn write_header(&mut self, tag: i8) -> Result<()> {
486        use serde::Serialize;
487        raw::write_bare_byte(&mut self.outer.writer, tag)?;
488        self.key
489            .serialize(&mut MapKeyEncoder::from_outer(self.outer))
490    }
491}
492
493impl<'a, 'b: 'a, W: 'a, K> serde::Serializer for &'a mut TagEncoder<'a, 'b, W, K>
494where
495    W: io::Write,
496    K: serde::Serialize,
497{
498    type Ok = ();
499    type Error = Error;
500    type SerializeSeq = NoOp;
501    type SerializeTuple = ser::Impossible<(), Error>;
502    type SerializeTupleStruct = NoOp;
503    type SerializeTupleVariant = ser::Impossible<(), Error>;
504    type SerializeMap = NoOp;
505    type SerializeStruct = NoOp;
506    type SerializeStructVariant = ser::Impossible<(), Error>;
507
508    unrepresentable!(
509        u8 u16 u32 u64 char unit newtype_variant tuple
510            tuple_variant struct_variant
511    );
512
513    #[inline]
514    fn serialize_bool(self, value: bool) -> Result<()> {
515        self.serialize_i8(value as i8)
516    }
517
518    #[inline]
519    fn serialize_i8(self, _value: i8) -> Result<()> {
520        self.write_header(0x01)
521    }
522
523    #[inline]
524    fn serialize_i16(self, _value: i16) -> Result<()> {
525        self.write_header(0x02)
526    }
527
528    #[inline]
529    fn serialize_i32(self, _value: i32) -> Result<()> {
530        self.write_header(0x03)
531    }
532
533    #[inline]
534    fn serialize_i64(self, _value: i64) -> Result<()> {
535        self.write_header(0x04)
536    }
537
538    #[inline]
539    fn serialize_f32(self, _value: f32) -> Result<()> {
540        self.write_header(0x05)
541    }
542
543    #[inline]
544    fn serialize_f64(self, _value: f64) -> Result<()> {
545        self.write_header(0x06)
546    }
547
548    #[inline]
549    fn serialize_str(self, _value: &str) -> Result<()> {
550        self.write_header(0x08)
551    }
552
553    #[inline]
554    fn serialize_unit_variant(
555        self,
556        _name: &'static str,
557        _variant_index: u32,
558        variant: &'static str,
559    ) -> Result<()> {
560        self.serialize_str(variant)
561    }
562
563    #[inline]
564    fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
565        Err(Error::UnrepresentableType("u8"))
566    }
567
568    #[inline]
569    fn serialize_none(self) -> Result<()> {
570        Ok(())
571    }
572
573    #[inline]
574    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
575    where
576        T: ser::Serialize,
577    {
578        value.serialize(self)
579    }
580
581    #[inline]
582    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
583        self.write_header(0x0a)
584    }
585
586    #[inline]
587    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<()>
588    where
589        T: ser::Serialize,
590    {
591        value.serialize(self)
592    }
593
594    #[inline]
595    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
596        if len.is_some() {
597            self.write_header(0x09)?;
598            Ok(NoOp)
599        } else {
600            Err(Error::UnrepresentableType("unsized list"))
601        }
602    }
603
604    #[inline]
605    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
606        self.write_header(0x0a)?;
607        Ok(NoOp)
608    }
609
610    #[inline]
611    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
612        self.write_header(0x0a)?;
613        Ok(NoOp)
614    }
615
616    fn serialize_tuple_struct(
617        self,
618        name: &'static str,
619        _len: usize,
620    ) -> Result<Self::SerializeTupleStruct> {
621        match name {
622            "__hematite_nbt_i8_array__" => self.write_header(0x07)?,
623            "__hematite_nbt_i32_array__" => self.write_header(0x0b)?,
624            "__hematite_nbt_i64_array__" => self.write_header(0x0c)?,
625            _ => return Err(Error::UnrepresentableType("tuple struct")),
626        }
627
628        Ok(NoOp)
629    }
630}
631
632/// This empty serializer provides a way to serialize only headers/tags for
633/// sequences, maps, and structs.
634struct NoOp;
635
636impl ser::SerializeSeq for NoOp {
637    type Ok = ();
638    type Error = Error;
639
640    fn serialize_element<T: ?Sized>(&mut self, _value: &T) -> Result<()>
641    where
642        T: serde::Serialize,
643    {
644        Ok(())
645    }
646
647    fn end(self) -> Result<()> {
648        Ok(())
649    }
650}
651
652impl ser::SerializeTupleStruct for NoOp {
653    type Ok = ();
654    type Error = Error;
655
656    fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()>
657    where
658        T: serde::Serialize,
659    {
660        Ok(())
661    }
662
663    fn end(self) -> Result<()> {
664        Ok(())
665    }
666}
667
668impl ser::SerializeStruct for NoOp {
669    type Ok = ();
670    type Error = Error;
671
672    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, _value: &T) -> Result<()>
673    where
674        T: serde::Serialize,
675    {
676        Ok(())
677    }
678
679    fn end(self) -> Result<()> {
680        Ok(())
681    }
682}
683
684impl ser::SerializeMap for NoOp {
685    type Ok = ();
686    type Error = Error;
687
688    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
689    where
690        T: serde::Serialize,
691    {
692        Ok(())
693    }
694
695    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
696    where
697        T: serde::Serialize,
698    {
699        Ok(())
700    }
701
702    fn end(self) -> Result<()> {
703        Ok(())
704    }
705}
706
707/// This function provides serde serialization support for NBT type `ByteArray`.
708///
709/// It should be used in conjunction with serde's field annotation `serialize_with`.
710/// In the following example `byte_data` will be serialized as a `ByteArray`
711/// instead of a `List` of `Byte`s:
712///
713/// ```
714/// extern crate serde;
715/// use nbt::to_writer;
716/// use serde::Serialize;
717///
718/// let mut serialized = Vec::new();
719///
720/// // Declare your struct
721/// #[derive(Serialize)]
722/// struct Sheep {
723///     #[serde(serialize_with="nbt::i8_array")]
724///     byte_data: Vec<i8>,
725/// }
726///
727/// // Serialize to NBT!
728/// to_writer(
729///     &mut serialized,
730///     &Sheep {
731///         byte_data: vec![0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x73, 0x68, 0x65, 0x65, 0x70],
732///     },
733///     None
734/// ).unwrap();
735///
736/// print!("Serialized: {:?}", serialized);
737/// ```
738pub fn i8_array<T, S>(array: T, serializer: S) -> std::result::Result<S::Ok, S::Error>
739where
740    T: IntoIterator,
741    <T as IntoIterator>::Item: std::borrow::Borrow<i8>,
742    S: serde::ser::Serializer,
743{
744    array_serializer!("i8_array", array, serializer)
745}
746
747/// This function provides serde serialization support for NBT type `IntArray`.
748///
749/// It should be used in conjunction with serde's field annotation `serialize_with`.
750/// In the following example `int_data` will be serialized as an `IntArray`
751/// instead of a `List` of `Int`s:
752///
753/// ```
754/// extern crate serde;
755/// use nbt::to_writer;
756/// use serde::Serialize;
757///
758/// let mut serialized = Vec::new();
759///
760/// // Declare your struct
761/// #[derive(Serialize)]
762/// struct Cow {
763///     #[serde(serialize_with="nbt::i32_array")]
764///     int_data: Vec<i32>,
765/// }
766///
767/// // Serialize to NBT!
768/// to_writer(
769///     &mut serialized,
770///     &Cow {
771///         int_data: vec![1, 8, 64, 512, 4096, 32768, 262144],
772///     },
773///     None
774/// ).unwrap();
775///
776/// print!("Serialized: {:?}", serialized);
777/// ```
778pub fn i32_array<T, S>(array: T, serializer: S) -> std::result::Result<S::Ok, S::Error>
779where
780    T: IntoIterator,
781    <T as IntoIterator>::Item: std::borrow::Borrow<i32>,
782    S: serde::ser::Serializer,
783{
784    array_serializer!("i32_array", array, serializer)
785}
786
787/// This function provides serde serialization support for NBT type `LongArray`.
788///
789/// It should be used in conjunction with serde's field annotation `serialize_with`.
790/// In the following example `int_data` will be serialized as a `LongArray`
791/// instead of a `List` of `Int`s:
792///
793/// ```
794/// extern crate serde;
795/// use nbt::to_writer;
796/// use serde::Serialize;
797///
798/// let mut serialized = Vec::new();
799///
800/// // Declare your struct
801/// #[derive(Serialize)]
802/// struct Enderman {
803///     #[serde(serialize_with="nbt::i64_array")]
804///     long_data: Vec<i64>,
805/// }
806///
807/// // Serialize to NBT!
808/// to_writer(
809///     &mut serialized,
810///     &Enderman {
811///         long_data: vec![0x1848ccd2157df10e, 0x64c5efff28280e9a],
812///     },
813///     None
814/// ).unwrap();
815///
816/// print!("Serialized: {:?}", serialized);
817/// ```
818pub fn i64_array<T, S>(array: T, serializer: S) -> std::result::Result<S::Ok, S::Error>
819where
820    T: IntoIterator,
821    <T as IntoIterator>::Item: std::borrow::Borrow<i64>,
822    S: serde::ser::Serializer,
823{
824    array_serializer!("i64_array", array, serializer)
825}