use crate::reader::tape::TapeElement;
use lexical_core::FormattedSize;
use serde::ser::{
Impossible, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct,
};
use serde::{Serialize, Serializer};
#[derive(Debug)]
pub struct SerializerError(String);
impl std::error::Error for SerializerError {}
impl std::fmt::Display for SerializerError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl serde::ser::Error for SerializerError {
fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
Self(msg.to_string())
}
}
pub struct TapeSerializer<'a> {
elements: &'a mut Vec<TapeElement>,
bytes: &'a mut Vec<u8>,
offsets: &'a mut Vec<usize>,
}
impl<'a> TapeSerializer<'a> {
pub fn new(
elements: &'a mut Vec<TapeElement>,
bytes: &'a mut Vec<u8>,
offsets: &'a mut Vec<usize>,
) -> Self {
Self {
elements,
bytes,
offsets,
}
}
fn serialize_number(&mut self, v: &[u8]) {
self.bytes.extend_from_slice(v);
let idx = self.offsets.len() - 1;
self.elements.push(TapeElement::Number(idx as _));
self.offsets.push(self.bytes.len());
}
}
impl<'a, 'b> Serializer for &'a mut TapeSerializer<'b> {
type Ok = ();
type Error = SerializerError;
type SerializeSeq = ListSerializer<'a, 'b>;
type SerializeTuple = ListSerializer<'a, 'b>;
type SerializeTupleStruct = ListSerializer<'a, 'b>;
type SerializeTupleVariant = Impossible<(), SerializerError>;
type SerializeMap = ObjectSerializer<'a, 'b>;
type SerializeStruct = ObjectSerializer<'a, 'b>;
type SerializeStructVariant = Impossible<(), SerializerError>;
fn serialize_bool(self, v: bool) -> Result<(), SerializerError> {
self.elements.push(match v {
true => TapeElement::True,
false => TapeElement::False,
});
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<(), SerializerError> {
self.serialize_i32(v as _)
}
fn serialize_i16(self, v: i16) -> Result<(), SerializerError> {
self.serialize_i32(v as _)
}
fn serialize_i32(self, v: i32) -> Result<(), SerializerError> {
self.elements.push(TapeElement::I32(v));
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<(), SerializerError> {
let low = v as i32;
let high = (v >> 32) as i32;
self.elements.push(TapeElement::I64(high));
self.elements.push(TapeElement::I32(low));
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<(), SerializerError> {
self.serialize_i32(v as _)
}
fn serialize_u16(self, v: u16) -> Result<(), SerializerError> {
self.serialize_i32(v as _)
}
fn serialize_u32(self, v: u32) -> Result<(), SerializerError> {
match i32::try_from(v) {
Ok(v) => self.serialize_i32(v),
Err(_) => self.serialize_i64(v as _),
}
}
fn serialize_u64(self, v: u64) -> Result<(), SerializerError> {
match i64::try_from(v) {
Ok(v) => self.serialize_i64(v),
Err(_) => {
let mut buffer = [0_u8; u64::FORMATTED_SIZE];
let s = lexical_core::write(v, &mut buffer);
self.serialize_number(s);
Ok(())
}
}
}
fn serialize_f32(self, v: f32) -> Result<(), SerializerError> {
self.elements.push(TapeElement::F32(v.to_bits()));
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<(), SerializerError> {
let bits = v.to_bits();
self.elements.push(TapeElement::F64((bits >> 32) as u32));
self.elements.push(TapeElement::F32(bits as u32));
Ok(())
}
fn serialize_char(self, v: char) -> Result<(), SerializerError> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<(), SerializerError> {
self.serialize_bytes(v.as_bytes())
}
fn serialize_bytes(self, v: &[u8]) -> Result<(), SerializerError> {
self.bytes.extend_from_slice(v);
let idx = self.offsets.len() - 1;
self.elements.push(TapeElement::String(idx as _));
self.offsets.push(self.bytes.len());
Ok(())
}
fn serialize_none(self) -> Result<(), SerializerError> {
self.serialize_unit()
}
fn serialize_some<T>(self, value: &T) -> Result<(), SerializerError>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<(), SerializerError> {
self.elements.push(TapeElement::Null);
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<(), SerializerError> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<(), SerializerError> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<(), SerializerError>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<(), SerializerError>
where
T: ?Sized + Serialize,
{
let mut serializer = self.serialize_map(Some(1))?;
serializer.serialize_key(variant)?;
serializer.serialize_value(value)?;
serializer.finish();
Ok(())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, SerializerError> {
Ok(ListSerializer::new(self))
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, SerializerError> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, SerializerError> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, SerializerError> {
Err(SerializerError(format!(
"serializing tuple variants is not currently supported: {name}::{variant}"
)))
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, SerializerError> {
Ok(ObjectSerializer::new(self))
}
fn serialize_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, SerializerError> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, SerializerError> {
Err(SerializerError(format!(
"serializing struct variants is not currently supported: {name}::{variant}"
)))
}
}
pub struct ObjectSerializer<'a, 'b> {
serializer: &'a mut TapeSerializer<'b>,
start: usize,
}
impl<'a, 'b> ObjectSerializer<'a, 'b> {
fn new(serializer: &'a mut TapeSerializer<'b>) -> Self {
let start = serializer.elements.len();
serializer.elements.push(TapeElement::StartObject(0));
Self { serializer, start }
}
fn finish(self) {
let end = self.serializer.elements.len() as _;
self.serializer.elements[self.start] = TapeElement::StartObject(end);
let end = TapeElement::EndObject(self.start as _);
self.serializer.elements.push(end);
}
}
impl SerializeMap for ObjectSerializer<'_, '_> {
type Ok = ();
type Error = SerializerError;
fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
key.serialize(&mut *self.serializer)
}
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
value.serialize(&mut *self.serializer)
}
fn end(self) -> Result<(), Self::Error> {
self.finish();
Ok(())
}
}
impl SerializeStruct for ObjectSerializer<'_, '_> {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
key.serialize(&mut *self.serializer)?;
value.serialize(&mut *self.serializer)
}
fn end(self) -> Result<(), Self::Error> {
self.finish();
Ok(())
}
}
pub struct ListSerializer<'a, 'b> {
serializer: &'a mut TapeSerializer<'b>,
start: usize,
}
impl<'a, 'b> ListSerializer<'a, 'b> {
fn new(serializer: &'a mut TapeSerializer<'b>) -> Self {
let start = serializer.elements.len();
serializer.elements.push(TapeElement::StartList(0));
Self { serializer, start }
}
fn finish(self) {
let end = self.serializer.elements.len() as _;
self.serializer.elements[self.start] = TapeElement::StartList(end);
let end = TapeElement::EndList(self.start as _);
self.serializer.elements.push(end);
}
}
impl SerializeSeq for ListSerializer<'_, '_> {
type Ok = ();
type Error = SerializerError;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
value.serialize(&mut *self.serializer)
}
fn end(self) -> Result<(), Self::Error> {
self.finish();
Ok(())
}
}
impl SerializeTuple for ListSerializer<'_, '_> {
type Ok = ();
type Error = SerializerError;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
value.serialize(&mut *self.serializer)
}
fn end(self) -> Result<(), Self::Error> {
self.finish();
Ok(())
}
}
impl SerializeTupleStruct for ListSerializer<'_, '_> {
type Ok = ();
type Error = SerializerError;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
value.serialize(&mut *self.serializer)
}
fn end(self) -> Result<(), Self::Error> {
self.finish();
Ok(())
}
}