pub(crate) mod blocks;
pub use self::blocks::{block, doubly_labeled_block, labeled_block, Block, LabeledBlock};
use crate::format::{Format, Formatter};
use crate::structure::Body;
use crate::{Error, Identifier, Result};
use serde::ser::{self, Impossible, Serialize, SerializeStruct};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::fmt;
use std::io;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
#[doc(hidden)]
pub use crate::expr::to_expression;
thread_local! {
static INTERNAL_SERIALIZATION: AtomicBool = const { AtomicBool::new(false) };
}
pub(crate) fn in_internal_serialization() -> bool {
INTERNAL_SERIALIZATION.with(|flag| flag.load(Ordering::Relaxed))
}
pub(crate) fn with_internal_serialization<R, F: FnOnce() -> R>(f: F) -> R {
INTERNAL_SERIALIZATION.with(|flag| {
let old = flag.load(Ordering::Relaxed);
flag.store(true, Ordering::Relaxed);
let _on_drop = OnDrop::new(|| {
flag.store(old, Ordering::Relaxed);
});
f()
})
}
pub struct Serializer<'a, W> {
formatter: Formatter<'a, W>,
}
impl<'a, W> Serializer<'a, W>
where
W: io::Write,
{
pub fn new(writer: W) -> Serializer<'a, W> {
Serializer::with_formatter(Formatter::new(writer))
}
pub fn with_formatter(formatter: Formatter<'a, W>) -> Serializer<'a, W> {
Serializer { formatter }
}
pub fn into_inner(self) -> W {
self.formatter.into_inner()
}
pub fn serialize<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
let serialized = Body::from_serializable(value)?;
serialized.format(&mut self.formatter)
}
}
impl<W> Serializer<'_, W>
where
W: io::Write + AsMut<Vec<u8>>,
{
pub fn serialize_string<T>(&mut self, value: &T) -> Result<String>
where
T: ?Sized + Serialize,
{
let serialized = Body::from_serializable(value)?;
serialized.format_string(&mut self.formatter)
}
pub fn serialize_vec<T>(&mut self, value: &T) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
let serialized = Body::from_serializable(value)?;
serialized.format_vec(&mut self.formatter)
}
}
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
let mut serializer = Serializer::with_formatter(Formatter::default());
serializer.serialize_vec(value)
}
pub fn to_string<T>(value: &T) -> Result<String>
where
T: ?Sized + Serialize,
{
let mut serializer = Serializer::with_formatter(Formatter::default());
serializer.serialize_string(value)
}
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
where
W: io::Write,
T: ?Sized + Serialize,
{
let mut serializer = Serializer::new(writer);
serializer.serialize(value)
}
pub(crate) struct StringSerializer;
impl ser::Serializer for StringSerializer {
type Ok = String;
type Error = Error;
type SerializeSeq = Impossible<String, Error>;
type SerializeTuple = Impossible<String, Error>;
type SerializeTupleStruct = Impossible<String, Error>;
type SerializeTupleVariant = Impossible<String, Error>;
type SerializeMap = Impossible<String, Error>;
type SerializeStruct = Impossible<String, Error>;
type SerializeStructVariant = Impossible<String, Error>;
serialize_unsupported! {
i8 i16 i32 i64 u8 u16 u32 u64
bool f32 f64 bytes unit unit_struct newtype_variant none
seq tuple tuple_struct tuple_variant map struct struct_variant
}
serialize_self! { some newtype_struct }
fn serialize_char(self, value: char) -> Result<Self::Ok> {
Ok(value.to_string())
}
fn serialize_str(self, value: &str) -> Result<Self::Ok> {
Ok(value.to_owned())
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok> {
Ok(variant.to_owned())
}
fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
where
T: ?Sized + fmt::Display,
{
Ok(value.to_string())
}
}
pub(crate) struct IdentifierSerializer;
impl ser::Serializer for IdentifierSerializer {
type Ok = Identifier;
type Error = Error;
type SerializeSeq = Impossible<Identifier, Error>;
type SerializeTuple = Impossible<Identifier, Error>;
type SerializeTupleStruct = Impossible<Identifier, Error>;
type SerializeTupleVariant = Impossible<Identifier, Error>;
type SerializeMap = Impossible<Identifier, Error>;
type SerializeStruct = Impossible<Identifier, Error>;
type SerializeStructVariant = Impossible<Identifier, Error>;
serialize_unsupported! {
i8 i16 i32 i64 u8 u16 u32 u64
bool f32 f64 bytes unit unit_struct newtype_variant none
seq tuple tuple_struct tuple_variant map struct struct_variant
}
serialize_self! { some newtype_struct }
fn serialize_char(self, value: char) -> Result<Self::Ok> {
self.serialize_str(&value.to_string())
}
fn serialize_str(self, value: &str) -> Result<Self::Ok> {
Identifier::new(value)
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok> {
self.serialize_str(variant)
}
}
struct U64Serializer;
impl ser::Serializer for U64Serializer {
type Ok = u64;
type Error = Error;
type SerializeSeq = Impossible<u64, Error>;
type SerializeTuple = Impossible<u64, Error>;
type SerializeTupleStruct = Impossible<u64, Error>;
type SerializeTupleVariant = Impossible<u64, Error>;
type SerializeMap = Impossible<u64, Error>;
type SerializeStruct = Impossible<u64, Error>;
type SerializeStructVariant = Impossible<u64, Error>;
serialize_unsupported! {
i8 i16 i32 i64 u8 u16 u32 f32 f64 char str bool bytes
unit unit_variant unit_struct newtype_struct newtype_variant
some none seq tuple tuple_struct tuple_variant map struct struct_variant
}
fn serialize_u64(self, value: u64) -> Result<Self::Ok> {
Ok(value)
}
}
pub(crate) struct SerializeInternalHandleStruct {
handle: Option<u64>,
}
impl SerializeInternalHandleStruct {
pub(crate) fn new() -> Self {
SerializeInternalHandleStruct { handle: None }
}
}
impl ser::SerializeStruct for SerializeInternalHandleStruct {
type Ok = usize;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
assert_eq!(key, "handle", "bad handle struct");
self.handle = Some(value.serialize(U64Serializer)?);
Ok(())
}
fn end(self) -> Result<Self::Ok> {
let handle = self.handle.expect("bad handle reference in roundtrip");
Ok(handle as usize)
}
}
pub(crate) struct InternalHandles<T> {
marker: &'static str,
last_handle: AtomicUsize,
handles: RefCell<BTreeMap<usize, T>>,
}
impl<T> InternalHandles<T> {
pub(crate) fn new(marker: &'static str) -> InternalHandles<T> {
InternalHandles {
marker,
last_handle: AtomicUsize::new(0),
handles: RefCell::new(BTreeMap::new()),
}
}
pub(crate) fn remove(&self, handle: usize) -> T {
self.handles
.borrow_mut()
.remove(&handle)
.expect("handle not in registry")
}
pub(crate) fn serialize<V, S>(&self, value: V, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
V: Into<T>,
{
let handle = self.last_handle.fetch_add(1, Ordering::Relaxed);
self.handles.borrow_mut().insert(handle, value.into());
let mut s = serializer.serialize_struct(self.marker, 1)?;
s.serialize_field("handle", &handle)?;
s.end()
}
}
struct OnDrop<F: FnOnce()>(Option<F>);
impl<F: FnOnce()> OnDrop<F> {
fn new(f: F) -> Self {
Self(Some(f))
}
}
impl<F: FnOnce()> Drop for OnDrop<F> {
fn drop(&mut self) {
self.0.take().unwrap()();
}
}