Skip to main content

nbt/
ser.rs

1//! Serialize a Rust data structure into Named Binary Tag data.
2
3use std::io;
4
5use serde;
6use serde::ser;
7use flate2::Compression;
8use flate2::write::{GzEncoder, ZlibEncoder};
9
10use raw::{RawWriter, Endianness};
11
12use error::{Error, Result};
13
14/// Encode `value` in Named Binary Tag format to the given `io::Write`
15/// destination, with an optional header.
16#[inline]
17pub fn to_writer<'a, W, T>(dst: &mut W, value: &T, header: Option<&'a str>, endian: Endianness)
18                           -> Result<()>
19    where W: ?Sized + io::Write,
20          T: ?Sized + ser::Serialize,
21{
22    let mut encoder = Encoder::new(dst, header, endian);
23    value.serialize(&mut encoder)
24}
25
26/// Encode `value` in Named Binary Tag format to the given `io::Write`
27/// destination, with an optional header.
28pub fn to_gzip_writer<'a, W, T>(dst: &mut W, value: &T, header: Option<&'a str>, endian: Endianness)
29                           -> Result<()>
30    where W: ?Sized + io::Write,
31          T: ?Sized + ser::Serialize,
32{
33    let mut encoder = Encoder::new(GzEncoder::new(dst, Compression::Default), header, endian);
34    value.serialize(&mut encoder)
35}
36
37/// Encode `value` in Named Binary Tag format to the given `io::Write`
38/// destination, with an optional header.
39pub fn to_zlib_writer<'a, W, T>(dst: &mut W, value: &T, header: Option<&'a str>, endian: Endianness)
40                           -> Result<()>
41    where W: ?Sized + io::Write,
42          T: ?Sized + ser::Serialize,
43{
44    let mut encoder = Encoder::new(ZlibEncoder::new(dst, Compression::Default), header, endian);
45    value.serialize(&mut encoder)
46}
47
48/// Encode objects to Named Binary Tag format.
49///
50/// This structure can be used to serialize objects which implement the
51/// `serde::Serialize` trait into NBT format. Note that not all types are
52/// representable in NBT format (notably unsigned integers), so this encoder may
53/// return errors.
54pub struct Encoder<'a, W: io::Write> {
55    writer: RawWriter<W>,
56    header: Option<&'a str>,
57}
58
59impl<'a, W> Encoder<'a, W> where W: io::Write {
60
61    /// Create an encoder with optional `header` from a given Writer.
62    pub fn new(writer: W, header: Option<&'a str>, endian: Endianness) -> Self {
63        Encoder { writer: RawWriter::new(writer, endian), header: header }
64    }
65
66    /// Write the NBT tag and an optional header to the underlying writer.
67    #[inline]
68    fn write_header(&mut self, tag: i8, header: Option<&str>) -> Result<()> {
69        self.writer.write_bare_byte(tag)?;
70        match header {
71            None =>
72                self.writer.write_bare_short(0),
73            Some(h) =>
74                self.writer.write_bare_string(h),
75        }
76    }
77}
78
79/// "Inner" version of the NBT encoder, capable of serializing bare types.
80struct InnerEncoder<'a, 'b: 'a, W: io::Write + 'a> {
81    outer: &'a mut Encoder<'b, W>,
82}
83
84impl<'a, 'b, W> InnerEncoder<'a, 'b, W> where W: io::Write {
85    pub fn from_outer(outer: &'a mut Encoder<'b, W>) -> Self {
86        InnerEncoder { outer: outer }
87    }
88}
89
90#[doc(hidden)]
91pub struct Compound<'a, 'b: 'a, W: io::Write + 'a> {
92    outer: &'a mut Encoder<'b, W>,
93    length: i32,
94    sigil: bool,
95}
96
97impl<'a, 'b, W> Compound<'a, 'b, W> where W: io::Write {
98    fn from_outer(outer: &'a mut Encoder<'b, W>) -> Self {
99        Compound { outer: outer, length: 0, sigil: false }
100    }
101
102    fn for_seq(outer: &'a mut Encoder<'b, W>, length: i32) -> Result<Self> {
103        // For an empty list, write TAG_End as the tag type.
104        if length == 0 {
105            outer.writer.write_bare_byte(0x00)?;
106            outer.writer.write_bare_int(0)?;
107        }
108        Ok(Compound { outer: outer, length: length, sigil: false })
109    }
110}
111
112impl<'a, 'b, W> ser::SerializeSeq for Compound<'a, 'b, W>
113    where W: io::Write
114{
115    type Ok = ();
116    type Error = Error;
117
118    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
119        where T: serde::Serialize
120    {
121        if !self.sigil {
122            value.serialize(&mut TagEncoder::from_outer(self.outer, Option::<String>::None))?;
123            self.outer.writer.write_bare_int(self.length)?;
124            self.sigil = true;
125        }
126        value.serialize(&mut InnerEncoder::from_outer(self.outer))
127    }
128
129    fn end(self) -> Result<()> {
130        Ok(())
131    }
132}
133
134impl<'a, 'b, W> ser::SerializeStruct for Compound<'a, 'b, W>
135    where W: io::Write
136{
137    type Ok = ();
138    type Error = Error;
139
140    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T)
141                                  -> Result<()>
142        where T: serde::Serialize
143    {
144        value.serialize(&mut TagEncoder::from_outer(self.outer, Some(key)))?;
145        value.serialize(&mut InnerEncoder::from_outer(self.outer))
146    }
147
148    fn end(self) -> Result<()> {
149        self.outer.writer.close_nbt()
150    }
151}
152
153impl<'a, 'b, W> ser::SerializeMap for Compound<'a, 'b, W>
154    where W: io::Write
155{
156    type Ok = ();
157    type Error = Error;
158
159    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
160        where T: serde::Serialize
161    {
162        unimplemented!()
163    }
164
165    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
166        where T: serde::Serialize
167    {
168        unimplemented!()
169    }
170
171    fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>
172        where K: serde::Serialize,
173              V: serde::Serialize,
174    {
175        value.serialize(&mut TagEncoder::from_outer(self.outer, Some(key)))?;
176        value.serialize(&mut InnerEncoder::from_outer(self.outer))
177    }
178
179    fn end(self) -> Result<()> {
180        self.outer.writer.close_nbt()
181    }
182}
183
184impl<'a, 'b, W> serde::Serializer for &'a mut Encoder<'b, W> where W: io::Write {
185    type Ok = ();
186    type Error = Error;
187    type SerializeSeq = ser::Impossible<(), Error>;
188    type SerializeTuple = ser::Impossible<(), Error>;
189    type SerializeTupleStruct = ser::Impossible<(), Error>;
190    type SerializeTupleVariant = ser::Impossible<(), Error>;
191    type SerializeMap = Compound<'a, 'b, W>;
192    type SerializeStruct = Compound<'a, 'b, W>;
193    type SerializeStructVariant = ser::Impossible<(), Error>;
194
195    return_expr_for_serialized_types!(
196        Err(Error::NoRootCompound); bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64
197            char str bytes none some unit unit_variant newtype_variant
198            seq tuple tuple_struct tuple_variant struct_variant
199    );
200
201    /// Serialize unit structs as empty `Tag_Compound` data.
202    #[inline]
203    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
204        let header = self.header; // Circumvent strange borrowing errors.
205        self.write_header(0x0a, header)?;
206        self.writer.close_nbt()
207    }
208
209    /// Serialize newtype structs by their underlying type. Note that this will
210    /// only be successful if the underyling type is a struct or a map.
211    #[inline]
212    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T)
213                                           -> Result<()>
214        where T: ser::Serialize
215    {
216        value.serialize(self)
217    }
218
219    /// Serialize maps as `Tag_Compound` data.
220    #[inline]
221    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
222        let header = self.header; // Circumvent strange borrowing errors.
223        self.write_header(0x0a, header)?;
224        Ok(Compound::from_outer(self))
225    }
226
227    /// Serialize structs as `Tag_Compound` data.
228    #[inline]
229    fn serialize_struct(self, _name: &'static str, _len: usize)
230                        -> Result<Self::SerializeStruct>
231    {
232        let header = self.header; // Circumvent strange borrowing errors.
233        self.write_header(0x0a, header)?;
234        Ok(Compound::from_outer(self))
235    }
236}
237
238impl<'a, 'b, W> serde::Serializer for &'a mut InnerEncoder<'a, 'b, W> where W: io::Write {
239    type Ok = ();
240    type Error = Error;
241    type SerializeSeq = Compound<'a, 'b, W>;
242    type SerializeTuple = ser::Impossible<(), Error>;
243    type SerializeTupleStruct = ser::Impossible<(), Error>;
244    type SerializeTupleVariant = ser::Impossible<(), Error>;
245    type SerializeMap = Compound<'a, 'b, W>;
246    type SerializeStruct = Compound<'a, 'b, W>;
247    type SerializeStructVariant = ser::Impossible<(), Error>;
248
249    unrepresentable!(
250        u8 u16 u32 u64 char unit unit_variant newtype_variant tuple tuple_struct
251            tuple_variant struct_variant
252    );
253
254    #[inline]
255    fn serialize_bool(self, value: bool) -> Result<()> {
256        self.serialize_i8(value as i8)
257    }
258
259    #[inline]
260    fn serialize_i8(self, value: i8) -> Result<()> {
261        self.outer.writer.write_bare_byte(value)
262    }
263
264    #[inline]
265    fn serialize_i16(self, value: i16) -> Result<()> {
266        self.outer.writer.write_bare_short(value)
267    }
268
269    #[inline]
270    fn serialize_i32(self, value: i32) -> Result<()> {
271        self.outer.writer.write_bare_int(value)
272    }
273
274    #[inline]
275    fn serialize_i64(self, value: i64) -> Result<()> {
276        self.outer.writer.write_bare_long(value)
277    }
278
279    #[inline]
280    fn serialize_f32(self, value: f32) -> Result<()> {
281        self.outer.writer.write_bare_float(value)
282    }
283
284    #[inline]
285    fn serialize_f64(self, value: f64) -> Result<()> {
286        self.outer.writer.write_bare_double(value)
287    }
288
289    #[inline]
290    fn serialize_str(self, value: &str) -> Result<()> {
291        self.outer.writer.write_bare_string(value)
292    }
293
294    #[inline]
295    fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
296        Err(Error::UnrepresentableType("u8"))
297    }
298
299    #[inline]
300    fn serialize_none(self) -> Result<()> {
301        Ok(())
302    }
303
304    #[inline]
305    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
306        where T: ser::Serialize
307    {
308        value.serialize(self)
309    }
310
311    #[inline]
312    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
313        self.outer.writer.close_nbt()
314    }
315
316    #[inline]
317    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T)
318                                           -> Result<()>
319        where T: ser::Serialize
320    {
321        value.serialize(self)
322    }
323
324    #[inline]
325    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
326        if let Some(l) = len {
327            Compound::for_seq(self.outer, l as i32)
328        } else {
329            Err(Error::UnrepresentableType("unsized list"))
330        }
331    }
332
333    #[inline]
334    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
335        Ok(Compound::from_outer(self.outer))
336    }
337
338    #[inline]
339    fn serialize_struct(self, _name: &'static str, _len: usize)
340                        -> Result<Self::SerializeStruct>
341    {
342        Ok(Compound::from_outer(self.outer))
343    }
344}
345
346/// A serializer for valid map keys, i.e. strings.
347struct MapKeyEncoder<'a, 'b: 'a, W: io::Write + 'a> {
348    outer: &'a mut Encoder<'b, W>,
349}
350
351impl<'a, 'b: 'a, W: 'a> MapKeyEncoder<'a, 'b, W> where W: io::Write {
352    pub fn from_outer(outer: &'a mut Encoder<'b, W>) -> Self {
353        MapKeyEncoder { outer: outer }
354    }
355}
356
357impl<'a, 'b: 'a, W: 'a> serde::Serializer for &'a mut MapKeyEncoder<'a, 'b, W>
358    where W: io::Write
359{
360    type Ok = ();
361    type Error = Error;
362    type SerializeSeq = ser::Impossible<(), Error>;
363    type SerializeTuple = ser::Impossible<(), Error>;
364    type SerializeTupleStruct = ser::Impossible<(), Error>;
365    type SerializeTupleVariant = ser::Impossible<(), Error>;
366    type SerializeMap = ser::Impossible<(), Error>;
367    type SerializeStruct = ser::Impossible<(), Error>;
368    type SerializeStructVariant = ser::Impossible<(), Error>;
369
370    return_expr_for_serialized_types!(
371        Err(Error::NonStringMapKey); bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64
372            char bytes unit unit_variant newtype_variant unit_struct seq tuple
373            tuple_struct tuple_variant struct_variant newtype_struct map struct
374    );
375
376    fn serialize_none(self) -> Result<()> {
377        Ok(())
378    }
379
380    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
381    where T: ser::Serialize
382    {
383        value.serialize(self)
384    }
385
386    fn serialize_str(self, value: &str) -> Result<()> {
387        self.outer.writer.write_bare_string(value)
388    }
389}
390
391/// A serializer for valid map keys.
392struct TagEncoder<'a, 'b: 'a, W: io::Write + 'a, K> {
393    outer: &'a mut Encoder<'b, W>,
394    key: Option<K>,
395}
396
397impl<'a, 'b: 'a, W: 'a, K> TagEncoder<'a, 'b, W, K>
398where W: io::Write,
399      K: serde::Serialize
400{
401    fn from_outer(outer: &'a mut Encoder<'b, W>, key: Option<K>) -> Self {
402        TagEncoder {
403            outer: outer, key: key
404        }
405    }
406
407    fn write_header(&mut self, tag: i8) -> Result<()> {
408        use serde::Serialize;
409        self.outer.writer.write_bare_byte(tag)?;
410        self.key.serialize(&mut MapKeyEncoder::from_outer(self.outer))
411    }
412}
413
414impl<'a, 'b: 'a, W: 'a, K> serde::Serializer for &'a mut TagEncoder<'a, 'b, W, K>
415where W: io::Write,
416      K: serde::Serialize
417{
418    type Ok = ();
419    type Error = Error;
420    type SerializeSeq = NoOp;
421    type SerializeTuple = ser::Impossible<(), Error>;
422    type SerializeTupleStruct = ser::Impossible<(), Error>;
423    type SerializeTupleVariant = ser::Impossible<(), Error>;
424    type SerializeMap = NoOp;
425    type SerializeStruct = NoOp;
426    type SerializeStructVariant = ser::Impossible<(), Error>;
427
428    unrepresentable!(
429        u8 u16 u32 u64 char unit unit_variant newtype_variant tuple tuple_struct
430            tuple_variant struct_variant
431    );
432
433    #[inline]
434    fn serialize_bool(self, value: bool) -> Result<()> {
435        self.serialize_i8(value as i8)
436    }
437
438    #[inline]
439    fn serialize_i8(self, _value: i8) -> Result<()> {
440        self.write_header(0x01)
441    }
442
443    #[inline]
444    fn serialize_i16(self, _value: i16) -> Result<()> {
445        self.write_header(0x02)
446    }
447
448    #[inline]
449    fn serialize_i32(self, _value: i32) -> Result<()> {
450        self.write_header(0x03)
451    }
452
453    #[inline]
454    fn serialize_i64(self, _value: i64) -> Result<()> {
455        self.write_header(0x04)
456    }
457
458    #[inline]
459    fn serialize_f32(self, _value: f32) -> Result<()> {
460        self.write_header(0x05)
461    }
462
463    #[inline]
464    fn serialize_f64(self, _value: f64) -> Result<()> {
465        self.write_header(0x06)
466    }
467
468    #[inline]
469    fn serialize_str(self, _value: &str) -> Result<()> {
470        self.write_header(0x08)
471    }
472
473    #[inline]
474    fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
475        Err(Error::UnrepresentableType("u8"))
476    }
477
478    #[inline]
479    fn serialize_none(self) -> Result<()> {
480        Ok(())
481    }
482
483    #[inline]
484    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<()>
485        where T: ser::Serialize
486    {
487        value.serialize(self)
488    }
489
490    #[inline]
491    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
492        self.write_header(0x0a)
493    }
494
495    #[inline]
496    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T)
497                                           -> Result<()>
498        where T: ser::Serialize
499    {
500        value.serialize(self)
501    }
502
503    #[inline]
504    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
505        if len.is_some() {
506            self.write_header(0x09)?;
507            Ok(NoOp)
508        } else {
509            Err(Error::UnrepresentableType("unsized list"))
510        }
511    }
512
513    #[inline]
514    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
515        self.write_header(0x0a)?;
516        Ok(NoOp)
517    }
518
519    #[inline]
520    fn serialize_struct(self, _name: &'static str, _len: usize)
521                        -> Result<Self::SerializeStruct>
522    {
523        self.write_header(0x0a)?;
524        Ok(NoOp)
525    }
526}
527
528/// This empty serializer provides a way to serialize only headers/tags for
529/// sequences, maps, and structs.
530struct NoOp;
531
532impl ser::SerializeSeq for NoOp {
533    type Ok = ();
534    type Error = Error;
535
536    fn serialize_element<T: ?Sized>(&mut self, _value: &T) -> Result<()>
537        where T: serde::Serialize
538    {
539        Ok(())
540    }
541
542    fn end(self) -> Result<()> {
543        Ok(())
544    }
545}
546
547impl ser::SerializeStruct for NoOp {
548    type Ok = ();
549    type Error = Error;
550
551    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, _value: &T)
552                                  -> Result<()>
553        where T: serde::Serialize
554    {
555        Ok(())
556    }
557
558    fn end(self) -> Result<()> {
559        Ok(())
560    }
561}
562
563impl ser::SerializeMap for NoOp {
564    type Ok = ();
565    type Error = Error;
566
567    fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
568        where T: serde::Serialize
569    {
570        Ok(())
571    }
572
573    fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
574        where T: serde::Serialize
575    {
576        Ok(())
577    }
578
579    fn end(self) -> Result<()> {
580        Ok(())
581    }
582}