use std::io::Write;
use serde::ser::{self, Serialize};
use crate::error::{Error, Result};
use crate::ext::{NT_COMPLEX, NT_RAW_VALUE, typed_array_tag};
use crate::header::*;
use crate::ser::{
BytesExtractor, TypedArrayWriteSink, U16Extractor, check_map_entry_count,
check_struct_field_count,
};
use crate::size::encode_size_to_array;
#[inline]
fn code_for_bytes(n: usize) -> u8 {
match n {
1 => 0,
2 => 1,
4 => 2,
8 => 3,
16 => 4,
_ => 0,
}
}
#[inline]
fn complex_header(class: u8, byte_code: u8, is_array: bool) -> u8 {
((byte_code & 0b111) << 5) | ((class & 0b11) << 3) | u8::from(is_array)
}
pub struct StreamingSerializer<W: Write> {
writer: W,
}
impl<W: Write> StreamingSerializer<W> {
pub fn new(writer: W) -> Self {
Self { writer }
}
pub fn into_inner(self) -> W {
self.writer
}
#[inline]
fn write_all(&mut self, bytes: &[u8]) -> Result<()> {
Ok(self.writer.write_all(bytes)?)
}
#[inline]
fn write_byte(&mut self, b: u8) -> Result<()> {
Ok(self.writer.write_all(&[b])?)
}
#[inline]
fn write_size(&mut self, n: u64) -> Result<()> {
let mut buf = [0u8; 8];
let used = encode_size_to_array(n, &mut buf);
Ok(self.writer.write_all(&buf[..used])?)
}
fn write_null(&mut self) -> Result<()> {
self.write_byte(0)
}
fn write_bool_value(&mut self, v: bool) -> Result<()> {
self.write_byte(if v { 0x18 } else { 0x08 })
}
fn write_signed_value<const N: usize, T: Into<i128>>(&mut self, v: T) -> Result<()> {
let code = code_for_bytes(N);
let header = make_header(TYPE_NUMBER, NUM_SIGNED, code);
self.write_byte(header)?;
let x: i128 = v.into();
let bytes = x.to_le_bytes();
self.write_all(&bytes[..N])
}
fn write_unsigned_value<const N: usize, T: Into<u128>>(&mut self, v: T) -> Result<()> {
let code = code_for_bytes(N);
let header = make_header(TYPE_NUMBER, NUM_UNSIGNED, code);
self.write_byte(header)?;
let x: u128 = v.into();
let bytes = x.to_le_bytes();
self.write_all(&bytes[..N])
}
fn write_float32_value(&mut self, v: f32) -> Result<()> {
self.write_byte(make_header(TYPE_NUMBER, NUM_FLOAT, 2))?;
self.write_all(&v.to_le_bytes())
}
fn write_float64_value(&mut self, v: f64) -> Result<()> {
self.write_byte(make_header(TYPE_NUMBER, NUM_FLOAT, 3))?;
self.write_all(&v.to_le_bytes())
}
fn write_bfloat16_bits(&mut self, bits: u16) -> Result<()> {
self.write_byte(make_header(TYPE_NUMBER, NUM_FLOAT, 0))?;
self.write_all(&bits.to_le_bytes())
}
fn write_float16_bits(&mut self, bits: u16) -> Result<()> {
self.write_byte(make_header(TYPE_NUMBER, NUM_FLOAT, 1))?;
self.write_all(&bits.to_le_bytes())
}
fn write_str_value(&mut self, s: &str) -> Result<()> {
self.write_byte(TYPE_STRING)?;
self.write_size(s.len() as u64)?;
self.write_all(s.as_bytes())
}
fn write_variant_object_prefix(&mut self, variant: &'static str) -> Result<()> {
self.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.write_size(1)?;
self.write_size(variant.len() as u64)?;
self.write_all(variant.as_bytes())
}
fn write_generic_array_header(&mut self, len: usize) -> Result<()> {
self.write_byte(TYPE_GENERIC_ARRAY)?;
self.write_size(len as u64)
}
fn write_bytes_typed_array(&mut self, bytes: &[u8]) -> Result<()> {
let header = make_header(TYPE_TYPED_ARRAY, ARRAY_UNSIGNED, 0);
self.write_byte(header)?;
self.write_size(bytes.len() as u64)?;
self.write_all(bytes)
}
fn write_typed_array_bytes(
&mut self,
class: u8,
byte_code: u8,
elem_size: usize,
payload: &[u8],
) -> Result<()> {
let header = make_header(TYPE_TYPED_ARRAY, class, byte_code);
self.write_byte(header)?;
debug_assert_eq!(
payload.len() % elem_size,
0,
"typed-array payload must be a whole number of elements"
);
let count = payload.len() / elem_size;
self.write_size(count as u64)?;
self.write_all(payload)
}
fn write_complex_single_payload(
&mut self,
class: u8,
byte_code: u8,
payload: &[u8],
) -> Result<()> {
let elem_bytes = (1usize << byte_code) * 2;
if payload.len() != elem_bytes {
return Err(Error::Mismatch("invalid complex payload size"));
}
self.write_byte(make_extension_header(EXT_COMPLEX))?;
self.write_byte(complex_header(class, byte_code, false))?;
self.write_all(payload)
}
}
impl<'a, W: Write> ser::Serializer for &'a mut StreamingSerializer<W> {
type Ok = ();
type Error = Error;
type SerializeSeq = StreamingSeqSerializer<'a, W>;
type SerializeTuple = StreamingSeqSerializer<'a, W>;
type SerializeTupleStruct = StreamingSeqSerializer<'a, W>;
type SerializeTupleVariant = StreamingVariantSeqSerializer<'a, W>;
type SerializeMap = StreamingMapSerializer<'a, W>;
type SerializeStruct = StreamingStructSerializer<'a, W>;
type SerializeStructVariant = StreamingVariantStructSerializer<'a, W>;
fn serialize_bool(self, v: bool) -> Result<()> {
self.write_bool_value(v)
}
fn serialize_i8(self, v: i8) -> Result<()> {
self.write_signed_value::<1, _>(v)
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.write_signed_value::<2, _>(v)
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.write_signed_value::<4, _>(v)
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.write_signed_value::<8, _>(v)
}
fn serialize_i128(self, v: i128) -> Result<()> {
self.write_signed_value::<16, _>(v)
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.write_unsigned_value::<1, _>(v)
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.write_unsigned_value::<2, _>(v)
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.write_unsigned_value::<4, _>(v)
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.write_unsigned_value::<8, _>(v)
}
fn serialize_u128(self, v: u128) -> Result<()> {
self.write_unsigned_value::<16, _>(v)
}
fn serialize_f32(self, v: f32) -> Result<()> {
self.write_float32_value(v)
}
fn serialize_f64(self, v: f64) -> Result<()> {
self.write_float64_value(v)
}
fn serialize_char(self, v: char) -> Result<()> {
let mut buf = [0u8; 4];
let s = v.encode_utf8(&mut buf);
self.serialize_str(s)
}
fn serialize_str(self, v: &str) -> Result<()> {
self.write_str_value(v)
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
self.write_bytes_typed_array(v)
}
fn serialize_none(self) -> Result<()> {
self.write_null()
}
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
self.write_null()
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.write_null()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<()> {
self.write_str_value(variant)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
name: &'static str,
value: &T,
) -> Result<()> {
match name {
"bf16" => {
let bits = value.serialize(U16Extractor)?;
self.write_bfloat16_bits(bits)
}
"f16" => {
let bits = value.serialize(U16Extractor)?;
self.write_float16_bits(bits)
}
NT_COMPLEX => {
let payload = value.serialize(BytesExtractor)?;
if payload.len() < 2 {
return Err(Error::Mismatch("invalid complex payload"));
}
self.write_complex_single_payload(payload[0], payload[1], &payload[2..])
}
NT_RAW_VALUE => {
let raw = value.serialize(BytesExtractor)?;
self.write_all(&raw)
}
_ => {
if let Some((class, byte_code, elem_size)) = typed_array_tag(name) {
value.serialize(TypedArrayWriteSink(move |bytes: &[u8]| {
self.write_typed_array_bytes(class, byte_code, elem_size, bytes)
}))
} else {
value.serialize(self)
}
}
}
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<()> {
self.write_variant_object_prefix(variant)?;
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
let len = len.ok_or(Error::Unsupported(
"streaming serializer requires known-length sequences",
))?;
Ok(StreamingSeqSerializer {
ser: self,
len,
mode: SeqMode::Detecting,
count: 0,
})
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.write_generic_array_header(len)?;
Ok(StreamingSeqSerializer {
ser: self,
len,
mode: SeqMode::Generic,
count: 0,
})
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.write_generic_array_header(len)?;
Ok(StreamingSeqSerializer {
ser: self,
len,
mode: SeqMode::Generic,
count: 0,
})
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
self.write_variant_object_prefix(variant)?;
self.write_generic_array_header(len)?;
Ok(StreamingVariantSeqSerializer {
inner: StreamingSeqSerializer {
ser: self,
len,
mode: SeqMode::Generic,
count: 0,
},
})
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
let len = len.ok_or(Error::Unsupported(
"streaming serializer requires known-length maps",
))?;
Ok(StreamingMapSerializer {
ser: self,
len,
mode: KeyMode::Unknown,
count: 0,
keys: 0,
})
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.write_size(len as u64)?;
Ok(StreamingStructSerializer::new(self, len))
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
self.write_variant_object_prefix(variant)?;
self.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.write_size(len as u64)?;
Ok(StreamingVariantStructSerializer {
inner: StreamingStructSerializer::new(self, len),
})
}
fn is_human_readable(&self) -> bool {
false
}
}
enum SeqMode {
Detecting,
Generic,
TypedUnsigned { byte_code: u8 },
TypedSigned { byte_code: u8 },
TypedFloat { byte_code: u8 },
TypedBool { byte_acc: u8, bit_idx: u8 },
TypedString,
TypedComplex { class: u8, byte_code: u8 },
}
impl SeqMode {
fn type_name(&self) -> &'static str {
match self {
SeqMode::Detecting => "unknown",
SeqMode::Generic => "generic",
SeqMode::TypedUnsigned { .. } => "unsigned",
SeqMode::TypedSigned { .. } => "signed",
SeqMode::TypedFloat { .. } => "float",
SeqMode::TypedBool { .. } => "bool",
SeqMode::TypedString => "string",
SeqMode::TypedComplex { .. } => "complex",
}
}
}
fn typed_array_mismatch(expected: &SeqMode, got: &str) -> Error {
Error::msg(format!(
"streaming typed array expected {} elements, got {}; \
use to_vec for heterogeneous sequences",
expected.type_name(),
got
))
}
pub struct StreamingSeqSerializer<'a, W: Write> {
ser: &'a mut StreamingSerializer<W>,
len: usize,
mode: SeqMode,
count: usize,
}
impl<'a, W: Write> StreamingSeqSerializer<'a, W> {
fn ensure_generic(&mut self) -> Result<()> {
match self.mode {
SeqMode::Generic => Ok(()),
SeqMode::Detecting => {
self.ser.write_generic_array_header(self.len)?;
self.mode = SeqMode::Generic;
Ok(())
}
_ => Err(typed_array_mismatch(&self.mode, "generic")),
}
}
}
struct StreamingElemSer<'a, 'b, W: Write> {
seq: &'b mut StreamingSeqSerializer<'a, W>,
}
impl<'a, 'b, W: Write> StreamingElemSer<'a, 'b, W> {
#[inline(always)]
fn emit_signed(&mut self, v: i128, bytes: usize) -> Result<()> {
let byte_code = code_for_bytes(bytes);
if let SeqMode::TypedSigned { byte_code: bc } = self.seq.mode
&& bc == byte_code
{
return self.seq.ser.write_all(&v.to_le_bytes()[..bytes]);
}
self.emit_signed_cold(v, bytes, byte_code)
}
#[cold]
#[inline(never)]
fn emit_signed_cold(&mut self, v: i128, bytes: usize, byte_code: u8) -> Result<()> {
match self.seq.mode {
SeqMode::Detecting => {
let header = make_header(TYPE_TYPED_ARRAY, ARRAY_SIGNED, byte_code);
self.seq.ser.write_byte(header)?;
self.seq.ser.write_size(self.seq.len as u64)?;
self.seq.mode = SeqMode::TypedSigned { byte_code };
}
_ => return Err(typed_array_mismatch(&self.seq.mode, "signed")),
}
self.seq.ser.write_all(&v.to_le_bytes()[..bytes])
}
#[inline(always)]
fn emit_unsigned(&mut self, v: u128, bytes: usize) -> Result<()> {
let byte_code = code_for_bytes(bytes);
if let SeqMode::TypedUnsigned { byte_code: bc } = self.seq.mode
&& bc == byte_code
{
return self.seq.ser.write_all(&v.to_le_bytes()[..bytes]);
}
self.emit_unsigned_cold(v, bytes, byte_code)
}
#[cold]
#[inline(never)]
fn emit_unsigned_cold(&mut self, v: u128, bytes: usize, byte_code: u8) -> Result<()> {
match self.seq.mode {
SeqMode::Detecting => {
let header = make_header(TYPE_TYPED_ARRAY, ARRAY_UNSIGNED, byte_code);
self.seq.ser.write_byte(header)?;
self.seq.ser.write_size(self.seq.len as u64)?;
self.seq.mode = SeqMode::TypedUnsigned { byte_code };
}
_ => return Err(typed_array_mismatch(&self.seq.mode, "unsigned")),
}
self.seq.ser.write_all(&v.to_le_bytes()[..bytes])
}
#[inline(always)]
fn emit_float(&mut self, raw: &[u8], byte_code: u8) -> Result<()> {
if let SeqMode::TypedFloat { byte_code: bc } = self.seq.mode
&& bc == byte_code
{
return self.seq.ser.write_all(raw);
}
self.emit_float_cold(raw, byte_code)
}
#[cold]
#[inline(never)]
fn emit_float_cold(&mut self, raw: &[u8], byte_code: u8) -> Result<()> {
match self.seq.mode {
SeqMode::Detecting => {
let header = make_header(TYPE_TYPED_ARRAY, ARRAY_FLOAT, byte_code);
self.seq.ser.write_byte(header)?;
self.seq.ser.write_size(self.seq.len as u64)?;
self.seq.mode = SeqMode::TypedFloat { byte_code };
}
_ => return Err(typed_array_mismatch(&self.seq.mode, "float")),
}
self.seq.ser.write_all(raw)
}
#[inline(always)]
fn emit_complex(&mut self, class: u8, byte_code: u8, payload: &[u8]) -> Result<()> {
if let SeqMode::TypedComplex {
class: c,
byte_code: bc,
} = self.seq.mode
&& c == class
&& bc == byte_code
{
return self.seq.ser.write_all(payload);
}
self.emit_complex_cold(class, byte_code, payload)
}
#[cold]
#[inline(never)]
fn emit_complex_cold(&mut self, class: u8, byte_code: u8, payload: &[u8]) -> Result<()> {
let elem_bytes = (1usize << byte_code) * 2;
if payload.len() != elem_bytes {
return Err(Error::Mismatch("invalid complex payload size"));
}
match self.seq.mode {
SeqMode::Detecting => {
self.seq
.ser
.write_byte(make_extension_header(EXT_COMPLEX))?;
self.seq
.ser
.write_byte(complex_header(class, byte_code, true))?;
self.seq.ser.write_size(self.seq.len as u64)?;
self.seq.mode = SeqMode::TypedComplex { class, byte_code };
}
_ => return Err(typed_array_mismatch(&self.seq.mode, "complex")),
}
self.seq.ser.write_all(payload)
}
}
impl<'a, 'b, W: Write> StreamingElemSer<'a, 'b, W> {
#[cold]
#[inline(never)]
fn serialize_bool_cold(&mut self, v: bool) -> Result<()> {
match self.seq.mode {
SeqMode::Detecting => {
let header = make_header(TYPE_TYPED_ARRAY, ARRAY_BOOL_OR_STRING, 0);
self.seq.ser.write_byte(header)?;
self.seq.ser.write_size(self.seq.len as u64)?;
self.seq.mode = SeqMode::TypedBool {
byte_acc: 0,
bit_idx: 0,
};
}
_ => return Err(typed_array_mismatch(&self.seq.mode, "bool")),
}
if v && let SeqMode::TypedBool { byte_acc, .. } = &mut self.seq.mode {
*byte_acc |= 1;
}
if let SeqMode::TypedBool { bit_idx, .. } = &mut self.seq.mode {
*bit_idx = 1;
}
Ok(())
}
#[cold]
#[inline(never)]
fn serialize_str_cold(&mut self, v: &str) -> Result<()> {
match self.seq.mode {
SeqMode::Detecting => {
let header = make_header(TYPE_TYPED_ARRAY, ARRAY_BOOL_OR_STRING, 1);
self.seq.ser.write_byte(header)?;
self.seq.ser.write_size(self.seq.len as u64)?;
self.seq.mode = SeqMode::TypedString;
}
_ => return Err(typed_array_mismatch(&self.seq.mode, "string")),
}
self.seq.ser.write_size(v.len() as u64)?;
self.seq.ser.write_all(v.as_bytes())
}
}
impl<'a, 'b, W: Write> ser::Serializer for &'b mut StreamingElemSer<'a, 'b, W> {
type Ok = ();
type Error = Error;
type SerializeSeq = StreamingSeqSerializer<'b, W>;
type SerializeTuple = StreamingSeqSerializer<'b, W>;
type SerializeTupleStruct = StreamingSeqSerializer<'b, W>;
type SerializeTupleVariant = StreamingVariantSeqSerializer<'b, W>;
type SerializeMap = StreamingMapSerializer<'b, W>;
type SerializeStruct = StreamingStructSerializer<'b, W>;
type SerializeStructVariant = StreamingVariantStructSerializer<'b, W>;
#[inline]
fn serialize_bool(self, v: bool) -> Result<()> {
if let SeqMode::TypedBool {
byte_acc, bit_idx, ..
} = &mut self.seq.mode
{
if v {
*byte_acc |= 1 << *bit_idx;
}
*bit_idx += 1;
if *bit_idx == 8 {
self.seq.ser.write_byte(*byte_acc)?;
*byte_acc = 0;
*bit_idx = 0;
}
return Ok(());
}
self.serialize_bool_cold(v)
}
#[inline]
fn serialize_i8(self, v: i8) -> Result<()> {
self.emit_signed(v as i128, 1)
}
#[inline]
fn serialize_i16(self, v: i16) -> Result<()> {
self.emit_signed(v as i128, 2)
}
#[inline]
fn serialize_i32(self, v: i32) -> Result<()> {
self.emit_signed(v as i128, 4)
}
#[inline]
fn serialize_i64(self, v: i64) -> Result<()> {
self.emit_signed(v as i128, 8)
}
#[inline]
fn serialize_i128(self, v: i128) -> Result<()> {
self.emit_signed(v, 16)
}
#[inline]
fn serialize_u8(self, v: u8) -> Result<()> {
self.emit_unsigned(v as u128, 1)
}
#[inline]
fn serialize_u16(self, v: u16) -> Result<()> {
self.emit_unsigned(v as u128, 2)
}
#[inline]
fn serialize_u32(self, v: u32) -> Result<()> {
self.emit_unsigned(v as u128, 4)
}
#[inline]
fn serialize_u64(self, v: u64) -> Result<()> {
self.emit_unsigned(v as u128, 8)
}
#[inline]
fn serialize_u128(self, v: u128) -> Result<()> {
self.emit_unsigned(v, 16)
}
#[inline]
fn serialize_f32(self, v: f32) -> Result<()> {
self.emit_float(&v.to_le_bytes(), 2)
}
#[inline]
fn serialize_f64(self, v: f64) -> Result<()> {
self.emit_float(&v.to_le_bytes(), 3)
}
fn serialize_char(self, v: char) -> Result<()> {
let mut buf = [0u8; 4];
self.serialize_str(v.encode_utf8(&mut buf))
}
#[inline]
fn serialize_str(self, v: &str) -> Result<()> {
if let SeqMode::TypedString = self.seq.mode {
self.seq.ser.write_size(v.len() as u64)?;
return self.seq.ser.write_all(v.as_bytes());
}
self.serialize_str_cold(v)
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
self.seq.ensure_generic()?;
self.seq.ser.write_bytes_typed_array(v)
}
fn serialize_none(self) -> Result<()> {
self.seq.ensure_generic()?;
self.seq.ser.write_null()
}
fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
self.seq.ensure_generic()?;
self.seq.ser.write_null()
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<()> {
self.seq.ensure_generic()?;
self.seq.ser.write_str_value(variant)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
name: &'static str,
value: &T,
) -> Result<()> {
match name {
"bf16" => {
let bits = value.serialize(U16Extractor)?;
self.emit_float(&bits.to_le_bytes(), 0)
}
"f16" => {
let bits = value.serialize(U16Extractor)?;
self.emit_float(&bits.to_le_bytes(), 1)
}
NT_COMPLEX => {
let payload = value.serialize(BytesExtractor)?;
if payload.len() < 2 {
return Err(Error::Mismatch("invalid complex payload"));
}
self.emit_complex(payload[0], payload[1], &payload[2..])
}
NT_RAW_VALUE => {
self.seq.ensure_generic()?;
let raw = value.serialize(BytesExtractor)?;
self.seq.ser.write_all(&raw)
}
_ => {
if let Some((class, byte_code, elem_size)) = typed_array_tag(name) {
self.seq.ensure_generic()?;
let ser = &mut *self.seq.ser;
value.serialize(TypedArrayWriteSink(move |bytes: &[u8]| {
ser.write_typed_array_bytes(class, byte_code, elem_size, bytes)
}))
} else {
value.serialize(self)
}
}
}
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<()> {
self.seq.ensure_generic()?;
self.seq.ser.write_variant_object_prefix(variant)?;
value.serialize(&mut *self.seq.ser)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
self.seq.ensure_generic()?;
let len = len.ok_or(Error::Unsupported(
"streaming serializer requires known-length sequences",
))?;
Ok(StreamingSeqSerializer {
ser: self.seq.ser,
len,
mode: SeqMode::Detecting,
count: 0,
})
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.seq.ensure_generic()?;
self.seq.ser.write_generic_array_header(len)?;
Ok(StreamingSeqSerializer {
ser: self.seq.ser,
len,
mode: SeqMode::Generic,
count: 0,
})
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.seq.ensure_generic()?;
self.seq.ser.write_generic_array_header(len)?;
Ok(StreamingSeqSerializer {
ser: self.seq.ser,
len,
mode: SeqMode::Generic,
count: 0,
})
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant> {
self.seq.ensure_generic()?;
self.seq.ser.write_variant_object_prefix(variant)?;
self.seq.ser.write_generic_array_header(len)?;
Ok(StreamingVariantSeqSerializer {
inner: StreamingSeqSerializer {
ser: self.seq.ser,
len,
mode: SeqMode::Generic,
count: 0,
},
})
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
self.seq.ensure_generic()?;
let len = len.ok_or(Error::Unsupported(
"streaming serializer requires known-length maps",
))?;
Ok(StreamingMapSerializer {
ser: self.seq.ser,
len,
mode: KeyMode::Unknown,
count: 0,
keys: 0,
})
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.seq.ensure_generic()?;
self.seq.ser.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.seq.ser.write_size(len as u64)?;
Ok(StreamingStructSerializer::new(self.seq.ser, len))
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant> {
self.seq.ensure_generic()?;
self.seq.ser.write_variant_object_prefix(variant)?;
self.seq.ser.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.seq.ser.write_size(len as u64)?;
Ok(StreamingVariantStructSerializer {
inner: StreamingStructSerializer::new(self.seq.ser, len),
})
}
fn is_human_readable(&self) -> bool {
false
}
}
impl<'a, W: Write> ser::SerializeSeq for StreamingSeqSerializer<'a, W> {
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
if matches!(self.mode, SeqMode::Generic) {
value.serialize(&mut *self.ser)?;
} else {
let mut elem = StreamingElemSer { seq: self };
value.serialize(&mut elem)?;
}
self.count += 1;
Ok(())
}
fn end(self) -> Result<()> {
if let SeqMode::TypedBool { byte_acc, bit_idx } = self.mode
&& bit_idx != 0
{
self.ser.write_byte(byte_acc)?;
}
if matches!(self.mode, SeqMode::Detecting) {
self.ser.write_generic_array_header(self.len)?;
}
Ok(())
}
}
impl<'a, W: Write> ser::SerializeTuple for StreamingSeqSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
impl<'a, W: Write> ser::SerializeTupleStruct for StreamingSeqSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self)
}
}
pub struct StreamingVariantSeqSerializer<'a, W: Write> {
inner: StreamingSeqSerializer<'a, W>,
}
impl<'a, W: Write> ser::SerializeTupleVariant for StreamingVariantSeqSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
ser::SerializeSeq::serialize_element(&mut self.inner, value)
}
fn end(self) -> Result<()> {
ser::SerializeSeq::end(self.inner)
}
}
enum KeyMode {
Unknown,
String,
Signed(u8),
Unsigned(u8),
}
pub struct StreamingMapSerializer<'a, W: Write> {
ser: &'a mut StreamingSerializer<W>,
len: usize,
mode: KeyMode,
count: usize,
keys: usize,
}
impl<'a, W: Write> ser::SerializeMap for StreamingMapSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
struct KeySer<'a, 'b, W: Write> {
map: &'b mut StreamingMapSerializer<'a, W>,
}
impl<'a, 'b, W: Write> KeySer<'a, 'b, W> {
fn emit_signed_key(&mut self, v: i128, bytes: usize) -> Result<()> {
let code = code_for_bytes(bytes);
match self.map.mode {
KeyMode::Unknown => {
self.map
.ser
.write_byte(make_header(TYPE_OBJECT, KEY_SIGNED, code))?;
self.map.ser.write_size(self.map.len as u64)?;
self.map.mode = KeyMode::Signed(code);
}
KeyMode::Signed(c) if c == code => {}
_ => {
return Err(Error::Mismatch(
"object keys must be homogeneous signed integers of same width",
));
}
}
let raw = v.to_le_bytes();
self.map.ser.write_all(&raw[..bytes])
}
fn emit_unsigned_key(&mut self, v: u128, bytes: usize) -> Result<()> {
let code = code_for_bytes(bytes);
match self.map.mode {
KeyMode::Unknown => {
self.map
.ser
.write_byte(make_header(TYPE_OBJECT, KEY_UNSIGNED, code))?;
self.map.ser.write_size(self.map.len as u64)?;
self.map.mode = KeyMode::Unsigned(code);
}
KeyMode::Unsigned(c) if c == code => {}
_ => {
return Err(Error::Mismatch(
"object keys must be homogeneous unsigned integers of same width",
));
}
}
let raw = v.to_le_bytes();
self.map.ser.write_all(&raw[..bytes])
}
}
impl<'a, 'b, W: Write> ser::Serializer for &'b mut KeySer<'a, 'b, W> {
type Ok = ();
type Error = Error;
type SerializeSeq = ser::Impossible<(), Error>;
type SerializeTuple = ser::Impossible<(), Error>;
type SerializeTupleStruct = ser::Impossible<(), Error>;
type SerializeTupleVariant = ser::Impossible<(), Error>;
type SerializeMap = ser::Impossible<(), Error>;
type SerializeStruct = ser::Impossible<(), Error>;
type SerializeStructVariant = ser::Impossible<(), Error>;
fn serialize_str(self, v: &str) -> Result<()> {
match self.map.mode {
KeyMode::Unknown => {
self.map.ser.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.map.ser.write_size(self.map.len as u64)?;
self.map.mode = KeyMode::String;
}
KeyMode::String => {}
_ => return Err(Error::Mismatch("object keys must be homogeneous")),
}
self.map.ser.write_size(v.len() as u64)?;
self.map.ser.write_all(v.as_bytes())
}
fn serialize_char(self, v: char) -> Result<()> {
let mut buf = [0; 4];
self.serialize_str(v.encode_utf8(&mut buf))
}
fn serialize_i8(self, v: i8) -> Result<()> {
self.emit_signed_key(v as i128, 1)
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.emit_signed_key(v as i128, 2)
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.emit_signed_key(v as i128, 4)
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.emit_signed_key(v as i128, 8)
}
fn serialize_i128(self, v: i128) -> Result<()> {
self.emit_signed_key(v, 16)
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.emit_unsigned_key(v as u128, 1)
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.emit_unsigned_key(v as u128, 2)
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.emit_unsigned_key(v as u128, 4)
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.emit_unsigned_key(v as u128, 8)
}
fn serialize_u128(self, v: u128) -> Result<()> {
self.emit_unsigned_key(v, 16)
}
fn serialize_bool(self, _v: bool) -> Result<()> {
Err(Error::InvalidType("boolean not allowed as object key"))
}
fn serialize_f32(self, _v: f32) -> Result<()> {
Err(Error::InvalidType("float not allowed as object key"))
}
fn serialize_f64(self, _v: f64) -> Result<()> {
Err(Error::InvalidType("float not allowed as object key"))
}
fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
Err(Error::InvalidType("bytes not allowed as object key"))
}
fn serialize_none(self) -> Result<()> {
Err(Error::InvalidType("none not allowed as object key"))
}
fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> Result<()> {
Err(Error::InvalidType("option not allowed as object key"))
}
fn serialize_unit(self) -> Result<()> {
Err(Error::InvalidType("unit not allowed as object key"))
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
Err(Error::InvalidType("unit struct not allowed as object key"))
}
fn serialize_unit_variant(
self,
_name: &'static str,
_idx: u32,
_var: &'static str,
) -> Result<()> {
Err(Error::InvalidType("enum not allowed as object key"))
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_: &'static str,
_: &T,
) -> Result<()> {
Err(Error::InvalidType("newtype not allowed as object key"))
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(Error::InvalidType("enum not allowed as object key"))
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
Err(Error::InvalidType("seq not allowed as object key"))
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
Err(Error::InvalidType("tuple not allowed as object key"))
}
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(Error::InvalidType("tuple struct not allowed as object key"))
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(Error::InvalidType(
"tuple variant not allowed as object key",
))
}
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
Err(Error::InvalidType("map not allowed as object key"))
}
fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
Err(Error::InvalidType("struct not allowed as object key"))
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(Error::InvalidType(
"struct variant not allowed as object key",
))
}
fn is_human_readable(&self) -> bool {
false
}
}
let mut ks = KeySer { map: self };
key.serialize(&mut ks)?;
self.keys += 1;
Ok(())
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
value.serialize(&mut *self.ser)?;
self.count += 1;
Ok(())
}
fn end(self) -> Result<()> {
check_map_entry_count(Some(self.len), self.keys, self.count)?;
if matches!(self.mode, KeyMode::Unknown) {
self.ser.write_byte(TYPE_OBJECT | (KEY_STRING << 3))?;
self.ser.write_size(0)?;
}
Ok(())
}
}
pub struct StreamingStructSerializer<'a, W: Write> {
ser: &'a mut StreamingSerializer<W>,
declared: usize,
written: usize,
}
impl<'a, W: Write> StreamingStructSerializer<'a, W> {
fn new(ser: &'a mut StreamingSerializer<W>, declared: usize) -> Self {
Self {
ser,
declared,
written: 0,
}
}
}
impl<'a, W: Write> ser::SerializeStruct for StreamingStructSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
key: &'static str,
value: &T,
) -> Result<()> {
self.ser.write_size(key.len() as u64)?;
self.ser.write_all(key.as_bytes())?;
value.serialize(&mut *self.ser)?;
self.written += 1;
Ok(())
}
fn skip_field(&mut self, _key: &'static str) -> Result<()> {
Ok(())
}
fn end(self) -> Result<()> {
check_struct_field_count(self.declared, self.written)
}
}
pub struct StreamingVariantStructSerializer<'a, W: Write> {
inner: StreamingStructSerializer<'a, W>,
}
impl<'a, W: Write> ser::SerializeStructVariant for StreamingVariantStructSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
key: &'static str,
value: &T,
) -> Result<()> {
ser::SerializeStruct::serialize_field(&mut self.inner, key, value)
}
fn end(self) -> Result<()> {
ser::SerializeStruct::end(self.inner)
}
}
pub fn to_writer_streaming<W: Write, T: Serialize>(writer: W, value: &T) -> Result<()> {
let mut ser = StreamingSerializer::new(writer);
value.serialize(&mut ser)?;
Ok(ser.into_inner().flush()?)
}
#[derive(Default)]
struct CountingWriter {
len: u64,
}
impl Write for CountingWriter {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.len += buf.len() as u64;
Ok(buf.len())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.len += buf.len() as u64;
Ok(())
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
pub fn serialized_size<T: Serialize>(value: &T) -> Result<u64> {
let mut counter = StreamingSerializer::new(CountingWriter::default());
value.serialize(&mut counter)?;
Ok(counter.into_inner().len)
}