455 lines
9.3 KiB
Rust
455 lines
9.3 KiB
Rust
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<C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
out: W,
|
|
cfg: PhantomData<C>
|
|
}
|
|
|
|
impl<W> BaseSerializer<DefaultConfig, W>
|
|
where W: Write
|
|
{
|
|
pub fn new(out: W) -> Self {
|
|
Self::with_config(out)
|
|
}
|
|
}
|
|
|
|
impl<C, W> BaseSerializer<C, W>
|
|
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<R>(&mut self, r: R) -> Result<(), SerializerError<W::Error>>
|
|
where
|
|
C::RealSerializer: PrimitiveRealSerializer<R>
|
|
{
|
|
Ok(C::RealSerializer::serialize_real::<W>(&mut self.out, r)?)
|
|
}
|
|
|
|
#[inline]
|
|
fn write_delim(&mut self, delim: u8) -> Result<(), SerializerError<W::Error>> {
|
|
unsafe { Ok(self.out.write_delim_unchecked(delim)?) }
|
|
}
|
|
|
|
#[inline]
|
|
fn write_utf8(&mut self, slice: &[u8]) -> Result<(), SerializerError<W::Error>> {
|
|
unsafe { Ok(self.out.write_utf8_unchecked(slice)?) }
|
|
}
|
|
}
|
|
|
|
impl<'se, C, W> Serializer for &'se mut BaseSerializer<C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
type Error = SerializerError<W::Error>;
|
|
|
|
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::<u8>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_u16(self, real: u16) -> Result<(), Self::Error> {
|
|
self.serialize_real::<u16>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_u32(self, real: u32) -> Result<(), Self::Error> {
|
|
self.serialize_real::<u32>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_u64(self, real: u64) -> Result<(), Self::Error> {
|
|
self.serialize_real::<u64>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_i8(self, real: i8) -> Result<(), Self::Error> {
|
|
self.serialize_real::<i8>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_i16(self, real: i16) -> Result<(), Self::Error> {
|
|
self.serialize_real::<i16>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_i32(self, real: i32) -> Result<(), Self::Error> {
|
|
self.serialize_real::<i32>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_i64(self, real: i64) -> Result<(), Self::Error> {
|
|
self.serialize_real::<i64>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_f32(self, real: f32) -> Result<(), Self::Error> {
|
|
self.serialize_real::<f32>(real)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_real_f64(self, real: f64) -> Result<(), Self::Error> {
|
|
self.serialize_real::<f64>(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<Self::SerializeDict, Self::Error> {
|
|
SerializeDictBase::start(self)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_list_parts(self) -> Result<Self::SerializeList, Self::Error> {
|
|
SerializeListBase::start(self)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_multiline_text_parts(self) -> Result<Self::SerializeMultilineText, Self::Error> {
|
|
SerializeMultilineTextBase::start(self)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_multiline_text<'a, M>(self, lines: M) -> Result<(), Self::Error>
|
|
where M: IntoIterator<Item = &'a str>
|
|
{
|
|
SerializeMultilineTextBase::serialize(self, lines)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_list<V, L>(self, list: L) -> Result<(), Self::Error>
|
|
where
|
|
V: Serialize,
|
|
L: IntoIterator<Item = V>
|
|
{
|
|
SerializeListBase::serialize(self, list)
|
|
}
|
|
|
|
#[inline]
|
|
fn serialize_dict<K, V, D>(self, dict: D) -> Result<(), Self::Error>
|
|
where
|
|
K: Serialize,
|
|
V: Serialize,
|
|
D: IntoIterator<Item = (K, V)>
|
|
{
|
|
SerializeDictBase::serialize(self, dict)
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
pub struct SerializeListBase<'se, C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
ser: &'se mut BaseSerializer<C, W>,
|
|
first: bool
|
|
}
|
|
|
|
impl<'se, C, W> SerializeListBase<'se, C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
#[inline]
|
|
fn start(ser: &'se mut BaseSerializer<C, W>) -> Result<Self, SerializerError<W::Error>> {
|
|
ser.write_delim(GRAMMAR_PAREN_OPEN)?;
|
|
Ok(Self {
|
|
ser,
|
|
first: true
|
|
})
|
|
}
|
|
|
|
#[inline]
|
|
pub fn serialize<V, L>(ser: &'se mut BaseSerializer<C, W>, list: L) -> Result<(), SerializerError<W::Error>>
|
|
where
|
|
V: Serialize,
|
|
L: IntoIterator<Item = V>
|
|
{
|
|
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<W::Error>;
|
|
|
|
#[inline]
|
|
fn serialize_item<I>(&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<C, W>,
|
|
first: bool
|
|
}
|
|
|
|
impl<'se, C, W> SerializeDictBase<'se, C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
#[inline]
|
|
fn start(ser: &'se mut BaseSerializer<C, W>) -> Result<Self, SerializerError<W::Error>> {
|
|
ser.write_delim(GRAMMAR_BRACE_OPEN)?;
|
|
Ok(Self {
|
|
ser,
|
|
first: true
|
|
})
|
|
}
|
|
|
|
#[inline]
|
|
pub fn serialize<K, V, D>(ser: &'se mut BaseSerializer<C, W>, dict: D) -> Result<(), SerializerError<W::Error>>
|
|
where
|
|
K: Serialize,
|
|
V: Serialize,
|
|
D: IntoIterator<Item = (K, V)>
|
|
{
|
|
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<W::Error>;
|
|
|
|
#[inline]
|
|
fn serialize_kv<K, V>(&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<C, W>
|
|
}
|
|
|
|
impl<'se, C, W> SerializeMultilineTextBase<'se, C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
#[inline]
|
|
fn start(ser: &'se mut BaseSerializer<C, W>) -> Result<Self, SerializerError<W::Error>> {
|
|
ser.write_delim(GRAMMAR_BTICK)?;
|
|
Ok(Self {
|
|
ser
|
|
})
|
|
}
|
|
|
|
#[inline]
|
|
pub fn serialize<'a, L>(ser: &'se mut BaseSerializer<C, W>, lines: L) -> Result<(), SerializerError<W::Error>>
|
|
where
|
|
L: IntoIterator<Item = &'a str>
|
|
{
|
|
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<W::Error>;
|
|
|
|
#[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<C, W>
|
|
}
|
|
|
|
impl<'se, C, W> SerializeRealBase<'se, C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
#[inline]
|
|
fn new(ser: &'se mut BaseSerializer<C, W>) -> Result<Self, SerializerError<W::Error>> {
|
|
Ok(Self {
|
|
ser
|
|
})
|
|
}
|
|
}
|
|
|
|
impl<'se, C, W> SerializeRealPrimitive<u8> for SerializeRealBase<'se, C, W>
|
|
where
|
|
C: Config,
|
|
W: Write
|
|
{
|
|
type Error = SerializerError<W::Error>;
|
|
|
|
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
|
|
{}
|
|
|