use std::borrow::{Borrow, BorrowMut};
use serde::ser::{self, Impossible};
use serde::Serialize;
use internal::gob::Message;
use internal::types::TypeId;
use error::Error;
use schema::Schema;
use ser::{Output, OutputPart};
mod serialize_struct;
pub(crate) use self::serialize_struct::SerializeStructValue;
mod serialize_seq;
pub(crate) use self::serialize_seq::SerializeSeqValue;
mod serialize_tuple;
pub(crate) use self::serialize_tuple::SerializeTupleValue;
mod serialize_map;
pub(crate) use self::serialize_map::SerializeMapValue;
mod serialize_variant;
pub(crate) use self::serialize_variant::{SerializeStructVariantValue, SerializeVariantValue};
mod serialize_empty;
pub(crate) use self::serialize_empty::SerializeEmptyValue;
mod serialize_wire_types;
pub(crate) use self::serialize_wire_types::SerializeWireTypes;
pub(crate) struct SerializationOk<S> {
pub ctx: SerializationCtx<S>,
pub is_empty: bool,
}
pub(crate) struct SerializationCtx<S> {
pub schema: S,
pub value: Message<Vec<u8>>,
}
impl<S> SerializationCtx<S> {
pub(crate) fn with_schema(schema: S) -> Self {
SerializationCtx {
schema,
value: Message::new(Vec::new()),
}
}
pub(crate) fn with_borrow<F, E>(&mut self, f: F) -> Result<bool, E>
where
S: Borrow<Schema>,
F: FnOnce(SerializationCtx<&Schema>) -> Result<SerializationOk<&Schema>, E>,
{
let (is_empty, msg) = {
let buf = ::std::mem::replace(self.value.get_mut(), Vec::new());
let msg = Message::new(buf);
let ctx = SerializationCtx {
schema: self.schema.borrow(),
value: msg,
};
let ok = f(ctx)?;
(ok.is_empty, ok.ctx.value)
};
self.value = msg;
Ok(is_empty)
}
pub(crate) fn flush<O: Output>(&mut self, mut out: O) -> Result<(), Error>
where
S: BorrowMut<Schema>,
{
self.schema.borrow_mut().write_pending(&mut out)?;
let buffer = ::std::mem::replace(self.value.get_mut(), Vec::new());
out.serialize_part(OutputPart::new(buffer))
}
}
pub(crate) struct FieldValueSerializer<S> {
pub ctx: SerializationCtx<S>,
pub type_id: TypeId,
}
impl<S> FieldValueSerializer<S> {
fn check_type(&self, got: TypeId) -> Result<(), Error> {
if self.type_id != got {
Err(ser::Error::custom(format!(
"type id mismatch: got {}, expected {}",
got.0, self.type_id.0
)))
} else {
Ok(())
}
}
}
impl<S> ser::Serializer for FieldValueSerializer<S>
where
S: Borrow<Schema>,
{
type Ok = SerializationOk<S>;
type Error = Error;
type SerializeSeq = SerializeSeqValue<S>;
type SerializeTuple = SerializeTupleValue<S>;
type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
type SerializeMap = SerializeMapValue<S>;
type SerializeStruct = SerializeStructValue<S>;
type SerializeStructVariant = SerializeStructVariantValue<S>;
#[inline]
fn serialize_bool(mut self, v: bool) -> Result<Self::Ok, Self::Error> {
self.check_type(TypeId::BOOL)?;
self.ctx.value.write_bool(v);
Ok(SerializationOk {
ctx: self.ctx,
is_empty: v == false,
})
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i64(mut self, v: i64) -> Result<Self::Ok, Self::Error> {
self.check_type(TypeId::INT)?;
self.ctx.value.write_int(v);
Ok(SerializationOk {
ctx: self.ctx,
is_empty: v == 0,
})
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.serialize_u64(v as u64)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.serialize_u64(v as u64)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.serialize_u64(v as u64)
}
fn serialize_u64(mut self, v: u64) -> Result<Self::Ok, Self::Error> {
self.check_type(TypeId::UINT)?;
self.ctx.value.write_uint(v);
Ok(SerializationOk {
ctx: self.ctx,
is_empty: v == 0,
})
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.serialize_f64(v as f64)
}
fn serialize_f64(mut self, v: f64) -> Result<Self::Ok, Self::Error> {
self.check_type(TypeId::FLOAT)?;
self.ctx.value.write_float(v);
Ok(SerializationOk {
ctx: self.ctx,
is_empty: false,
})
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_str(mut self, v: &str) -> Result<Self::Ok, Self::Error> {
self.check_type(TypeId::STRING)?;
self.ctx.value.write_bytes(v.as_bytes());
Ok(SerializationOk {
ctx: self.ctx,
is_empty: v.len() == 0,
})
}
fn serialize_bytes(mut self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.check_type(TypeId::BYTES)?;
self.ctx.value.write_bytes(v);
Ok(SerializationOk {
ctx: self.ctx,
is_empty: v.len() == 0,
})
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
let value = {
let ser = FieldValueSerializer {
ctx: SerializationCtx {
schema: self.ctx.schema.borrow(),
value: self.ctx.value,
},
type_id: self.type_id,
};
let value = SerializeEmptyValue::new(self.ctx.schema.borrow(), self.type_id);
value.serialize(ser)?.ctx.value
};
Ok(SerializationOk {
ctx: SerializationCtx {
schema: self.ctx.schema,
value,
},
is_empty: true,
})
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("not implemented yet"))
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("not implemented yet"))
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("not implemented yet"))
}
fn serialize_newtype_struct<T: ?Sized>(
self,
_name: &'static str,
_value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(ser::Error::custom("not implemented yet"))
}
fn serialize_newtype_variant<T: ?Sized>(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
let ser = SerializeVariantValue::new(self.ctx, self.type_id, variant_index)?;
ser.serialize_newtype(value)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
SerializeSeqValue::new(self.ctx, len, self.type_id)
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
SerializeTupleValue::homogeneous(self.ctx, self.type_id)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(ser::Error::custom("not implemented yet"))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(ser::Error::custom("tuple variants not implemented yet"))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
SerializeMapValue::new(self.ctx, len, self.type_id)
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
SerializeStructValue::new(self.ctx, self.type_id)
}
fn serialize_struct_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
let ser = SerializeVariantValue::new(self.ctx, self.type_id, variant_index)?;
ser.serialize_struct()
}
}