mod real; mod error; use core::marker::PhantomData; use crate::grammar::*; use super::{ Serialize, Serializer, SerializeDict, SerializeList, SerializeMultilineText, SerializeReal, SerializeRealPrimitive }; use self::real::{ RealSerializer, PrimitiveRealSerializer, FastRealSerializer }; pub use self::error::*; pub trait Write { /// The core error that may bubble from /// attempting to write. type Error: WriteError; // fn write_delim(&mut self, delim: u8) -> Result<(), Self::Error>; // fn write_utf8(&mut self, slice: &[u8]) -> Result<(), Self::Error>; /// Write an ASCII byte (unchecked). unsafe fn write_delim_unchecked(&mut self, delim: u8) -> Result<(), Self::Error>; /// Write UTF8 bytes (unchecked). unsafe fn write_utf8_unchecked(&mut self, slice: &[u8]) -> Result<(), Self::Error>; } pub trait Config { type RealSerializer: RealSerializer; } pub struct DefaultConfig {} impl Config for DefaultConfig { type RealSerializer = FastRealSerializer; } pub struct BaseSerializer where C: Config, W: Write { out: W, cfg: PhantomData } impl BaseSerializer where W: Write { pub fn new(out: W) -> Self { Self::with_config(out) } } impl BaseSerializer where C: Config, W: Write { pub fn with_config(out: W) -> Self { Self { out, cfg: PhantomData } } pub fn into_inner(self) -> W { self.out } #[inline] pub fn serialize_real(&mut self, r: R) -> Result<(), SerializerError> where C::RealSerializer: PrimitiveRealSerializer { Ok(C::RealSerializer::serialize_real::(&mut self.out, r)?) } #[inline] fn write_delim(&mut self, delim: u8) -> Result<(), SerializerError> { unsafe { Ok(self.out.write_delim_unchecked(delim)?) } } #[inline] fn write_utf8(&mut self, slice: &[u8]) -> Result<(), SerializerError> { unsafe { Ok(self.out.write_utf8_unchecked(slice)?) } } } impl<'se, C, W> Serializer for &'se mut BaseSerializer where C: Config, W: Write { type Error = SerializerError; type SerializeReal = SerializeRealBase<'se, C, W>; type SerializeDict = SerializeDictBase<'se, C, W>; type SerializeList = SerializeListBase<'se, C, W>; type SerializeMultilineText = SerializeMultilineTextBase<'se, C, W>; #[inline] fn serialize_real_u8(self, real: u8) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_u16(self, real: u16) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_u32(self, real: u32) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_u64(self, real: u64) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_i8(self, real: i8) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_i16(self, real: i16) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_i32(self, real: i32) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_i64(self, real: i64) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_f32(self, real: f32) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_real_f64(self, real: f64) -> Result<(), Self::Error> { self.serialize_real::(real) } #[inline] fn serialize_unit<'a, V>(self, name: &'a str, value: V) -> Result<(), Self::Error> where V: Serialize { self.serialize_atom(name)?; self.write_delim(GRAMMAR_PAREN_OPEN)?; self.serialize_any(value)?; self.write_delim(GRAMMAR_PAREN_CLOSE) } #[inline] fn serialize_atom<'a>(self, atom: &'a str) -> Result<(), Self::Error> { self.write_utf8(atom.as_bytes()) } #[inline] fn serialize_text<'a>(self, text: &'a str) -> Result<(), Self::Error> { self.write_delim(GRAMMAR_QUOTE)?; self.write_utf8(text.as_bytes())?; self.write_delim(GRAMMAR_QUOTE) } #[inline] fn serialize_dict_parts(self) -> Result { SerializeDictBase::start(self) } #[inline] fn serialize_list_parts(self) -> Result { SerializeListBase::start(self) } #[inline] fn serialize_multiline_text_parts(self) -> Result { SerializeMultilineTextBase::start(self) } #[inline] fn serialize_multiline_text<'a, M>(self, lines: M) -> Result<(), Self::Error> where M: IntoIterator { SerializeMultilineTextBase::serialize(self, lines) } #[inline] fn serialize_list(self, list: L) -> Result<(), Self::Error> where V: Serialize, L: IntoIterator { SerializeListBase::serialize(self, list) } #[inline] fn serialize_dict(self, dict: D) -> Result<(), Self::Error> where K: Serialize, V: Serialize, D: IntoIterator { SerializeDictBase::serialize(self, dict) } } /////////////////////////////////////////////////////////////////////////////// pub struct SerializeListBase<'se, C, W> where C: Config, W: Write { ser: &'se mut BaseSerializer, first: bool } impl<'se, C, W> SerializeListBase<'se, C, W> where C: Config, W: Write { #[inline] fn start(ser: &'se mut BaseSerializer) -> Result> { ser.write_delim(GRAMMAR_PAREN_OPEN)?; Ok(Self { ser, first: true }) } #[inline] pub fn serialize(ser: &'se mut BaseSerializer, list: L) -> Result<(), SerializerError> where V: Serialize, L: IntoIterator { let mut state = ser.serialize_list_parts()?; for item in list.into_iter() { state.serialize_item(item)?; } state.end() } } impl<'se, C, W> SerializeList for SerializeListBase<'se, C, W> where C: Config, W: Write { type Error = SerializerError; #[inline] fn serialize_item(&mut self, item: I) -> Result<(), Self::Error> where I: Serialize { if self.first { self.first = false; } else { self.ser.write_delim(GRAMMAR_COMMA)?; } self.ser.serialize_any(&item) } #[inline] fn end(self) -> Result<(), Self::Error> { self.ser.write_delim(GRAMMAR_BRACE_CLOSE) } } /////////////////////////////////////////////////////////////////////////////// pub struct SerializeDictBase<'se, C, W> where C: Config, W: Write { ser: &'se mut BaseSerializer, first: bool } impl<'se, C, W> SerializeDictBase<'se, C, W> where C: Config, W: Write { #[inline] fn start(ser: &'se mut BaseSerializer) -> Result> { ser.write_delim(GRAMMAR_BRACE_OPEN)?; Ok(Self { ser, first: true }) } #[inline] pub fn serialize(ser: &'se mut BaseSerializer, dict: D) -> Result<(), SerializerError> where K: Serialize, V: Serialize, D: IntoIterator { let mut state = ser.serialize_dict_parts()?; for (key, value) in dict.into_iter() { state.serialize_kv(key, value)?; } state.end() } } impl<'se, C, W> SerializeDict for SerializeDictBase<'se, C, W> where C: Config, W: Write { type Error = SerializerError; #[inline] fn serialize_kv(&mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize { if self.first { self.first = false; } else { self.ser.write_delim(GRAMMAR_COMMA)?; } self.ser.serialize_any(&key)?; self.ser.write_delim(GRAMMAR_COLON)?; self.ser.serialize_any(&value) } #[inline] fn end(self) -> Result<(), Self::Error> { self.ser.write_delim(GRAMMAR_BRACE_CLOSE) } } /////////////////////////////////////////////////////////////////////////////// pub struct SerializeMultilineTextBase<'se, C, W> where C: Config, W: Write { ser: &'se mut BaseSerializer } impl<'se, C, W> SerializeMultilineTextBase<'se, C, W> where C: Config, W: Write { #[inline] fn start(ser: &'se mut BaseSerializer) -> Result> { ser.write_delim(GRAMMAR_BTICK)?; Ok(Self { ser }) } #[inline] pub fn serialize<'a, L>(ser: &'se mut BaseSerializer, lines: L) -> Result<(), SerializerError> where L: IntoIterator { let mut state = ser.serialize_multiline_text_parts()?; for line in lines.into_iter() { state.serialize_line(line)?; } state.end() } } impl<'se, C, W> SerializeMultilineText for SerializeMultilineTextBase<'se, C, W> where C: Config, W: Write { type Error = SerializerError; #[inline] fn serialize_line(&mut self, line: &str) -> Result<(), Self::Error> { self.ser.serialize_text(line) } #[inline] fn end(self) -> Result<(), Self::Error> { self.ser.write_delim(GRAMMAR_BTICK) } } /////////////////////////////////////////////////////////////////////////////// pub struct SerializeRealBase<'se, C, W> where C: Config, W: Write { ser: &'se mut BaseSerializer } impl<'se, C, W> SerializeRealBase<'se, C, W> where C: Config, W: Write { #[inline] fn new(ser: &'se mut BaseSerializer) -> Result> { Ok(Self { ser }) } } impl<'se, C, W> SerializeRealPrimitive for SerializeRealBase<'se, C, W> where C: Config, W: Write { type Error = SerializerError; fn serialize_real_primitive(self, real: u8) -> Result<(), Self::Error> { self.ser.write_utf8(real.to_string().as_bytes()) } } impl<'se, C, W> SerializeReal for SerializeRealBase<'se, C, W> where C: Config, W: Write {}