use std::fmt::Display; use serde::{ Serialize, ser::{self}, }; use super::{NetworkWriteExt, Write, WritingError}; pub struct Serializer { pub write: W, } impl Serializer { pub const fn new(w: W) -> Self { Self { write: w } } } impl ser::Error for WritingError { fn custom(msg: T) -> Self { Self::Message(msg.to_string()) } } // General notes on the serializer: // // Primitives are written as-is // Strings automatically prepend a VarInt // Enums are written as a VarInt of the index // Structs are ignored // Iterables' values are written in order, but NO information (e.g. size) about the // iterable itself is written (list sizes should be a separate field) impl ser::Serializer for &mut Serializer { type Ok = (); type Error = WritingError; type SerializeSeq = Self; type SerializeTuple = Self; type SerializeTupleStruct = Self; type SerializeTupleVariant = Self; type SerializeMap = Self; type SerializeStruct = Self; type SerializeStructVariant = Self; fn serialize_bool(self, v: bool) -> Result { self.write.write_bool(v) } fn serialize_bytes(self, v: &[u8]) -> Result { self.write.write_slice(v) } fn serialize_char(self, v: char) -> Result { self.write.write_u32_be(v as u32) } fn serialize_f32(self, v: f32) -> Result { self.write.write_f32_be(v) } fn serialize_f64(self, v: f64) -> Result { self.write.write_f64_be(v) } fn serialize_i128(self, v: i128) -> Result { self.write .write_all(&v.to_be_bytes()) .map_err(WritingError::IoError) } fn serialize_i16(self, v: i16) -> Result { self.write.write_i16_be(v) } fn serialize_i32(self, v: i32) -> Result { self.write.write_i32_be(v) } fn serialize_i64(self, v: i64) -> Result { self.write.write_i64_be(v) } fn serialize_i8(self, v: i8) -> Result { self.write.write_i8(v) } fn serialize_map(self, len: Option) -> Result { let Some(len) = len else { return Err(WritingError::Serde("Maps must have a known length".into())); }; self.write.write_var_int(&len.try_into().map_err(|_| { WritingError::Message(format!("{len} isn't representable as a VarInt")) })?)?; Ok(self) } fn serialize_newtype_struct( self, name: &'static str, value: &T, ) -> Result { // TODO: This is super sketchy... is there a way to do it better? Can we choose what // serializer to use on a struct somehow from within the struct? if name == "TextComponent" { let mut nbt_serializer = pumpkin_nbt::serializer::Serializer::new(&mut self.write, None); value.serialize(&mut nbt_serializer).map_err(|err| { WritingError::Serde(format!("Failed to serialize TextComponent NBT: {err}")) }) } else { value.serialize(self) } } fn serialize_newtype_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, value: &T, ) -> Result { self.write .write_var_int(&variant_index.try_into().map_err(|_| { WritingError::Message(format!("{variant_index} isn't representable as a VarInt")) })?)?; value.serialize(self) } fn serialize_none(self) -> Result { self.write.write_bool(false) } fn serialize_seq(self, len: Option) -> Result { let Some(len) = len else { return Err(WritingError::Serde( "Sequences must have a known length".into(), )); }; self.write.write_var_int(&len.try_into().map_err(|_| { WritingError::Message(format!("{len} isn't representable as a VarInt")) })?)?; Ok(self) } fn serialize_some(self, value: &T) -> Result { self.write.write_bool(true)?; value.serialize(self) } fn serialize_str(self, v: &str) -> Result { self.write.write_string(v) } fn serialize_struct( self, _name: &'static str, _len: usize, ) -> Result { Ok(self) } fn serialize_struct_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, _len: usize, ) -> Result { // Serialize ENUM index as varint self.write .write_var_int(&variant_index.try_into().map_err(|_| { WritingError::Message(format!("{variant_index} isn't representable as a VarInt")) })?)?; Ok(self) } fn serialize_tuple(self, _len: usize) -> Result { Ok(self) } fn serialize_tuple_struct( self, _name: &'static str, _len: usize, ) -> Result { Ok(self) } fn serialize_tuple_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, _len: usize, ) -> Result { // Serialize ENUM index as varint self.write .write_var_int(&variant_index.try_into().map_err(|_| { WritingError::Message(format!("{variant_index} isn't representable as a VarInt")) })?)?; Ok(self) } fn serialize_u128(self, v: u128) -> Result { self.write .write_all(&v.to_be_bytes()) .map_err(WritingError::IoError) } fn serialize_u16(self, v: u16) -> Result { self.write.write_u16_be(v) } fn serialize_u32(self, v: u32) -> Result { self.write.write_u32_be(v) } fn serialize_u64(self, v: u64) -> Result { self.write.write_u64_be(v) } fn serialize_u8(self, v: u8) -> Result { self.write.write_u8(v) } fn serialize_unit(self) -> Result { Ok(()) } fn serialize_unit_struct(self, _name: &'static str) -> Result { Ok(()) } fn serialize_unit_variant( self, _name: &'static str, variant_index: u32, _variant: &'static str, ) -> Result { // For ENUMs, only write enum index as varint self.write .write_var_int(&variant_index.try_into().map_err(|_| { WritingError::Message(format!("{variant_index} isn't representable as a VarInt")) })?) } fn is_human_readable(&self) -> bool { false } } impl ser::SerializeSeq for &mut Serializer { // Must match the `Ok` type of the serializer. type Ok = (); // Must match the `Error` type of the serializer. type Error = WritingError; // Serialize a single element of the sequence. fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { value.serialize(&mut **self) } // Close the sequence. fn end(self) -> Result<(), Self::Error> { Ok(()) } } impl ser::SerializeTuple for &mut Serializer { type Ok = (); type Error = WritingError; fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { Ok(()) } } // Same thing but for tuple structs. impl ser::SerializeTupleStruct for &mut Serializer { type Ok = (); type Error = WritingError; fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> { value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { Ok(()) } } // Tuple variants are a little different. Refer back to the // `serialize_tuple_variant` method above: // // self.write += "{"; // variant.serialize(&mut *self)?; // self.write += ":["; // // So the `end` method in this impl is responsible for closing both the `]` and // the `}`. impl ser::SerializeTupleVariant for &mut Serializer { type Ok = (); type Error = WritingError; fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> { value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { Ok(()) } } // Some `Serialize` types are not able to hold a key and value in memory at the // same time, so `SerializeMap` implementations are required to support // `serialize_key` and `serialize_value` individually. // // There is a third optional method on the `SerializeMap` trait. The // `serialize_entry` method allows serializers to optimize for the case where // key and value are both available simultaneously. In JSON it doesn't make a // difference, so the default behavior for `serialize_entry` is fine. impl ser::SerializeMap for &mut Serializer { type Ok = (); type Error = WritingError; fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> { key.serialize(&mut **self) } fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> { value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { Ok(()) } } // Structs are like maps in which the keys are constrained to be compile-time // constant strings. impl ser::SerializeStruct for &mut Serializer { type Ok = (); type Error = WritingError; fn serialize_field( &mut self, _key: &'static str, value: &T, ) -> Result<(), Self::Error> { value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { Ok(()) } fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { let _ = key; Ok(()) } } // Similar to `SerializeTupleVariant`, here the `end` method is responsible for // closing both of the curly braces opened by `serialize_struct_variant`. impl ser::SerializeStructVariant for &mut Serializer { type Ok = (); type Error = WritingError; fn serialize_field( &mut self, _key: &'static str, value: &T, ) -> Result<(), Self::Error> { value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { Ok(()) } }