use super::{
super::{annotate::*, normal::*, *},
errors::*,
modal::*,
mode::*,
};
use {kutil::std::immutable::*, serde::*, std::io};
const STRINGIFY_BUFFER_CAPACITY: usize = 1024;
#[derive(Clone)]
pub struct Serializer {
pub format: Format,
pub pretty: bool,
pub indent: u64,
pub base64: bool,
}
impl Serializer {
pub fn new(format: Format) -> Self {
Self { format, pretty: false, indent: 2, base64: false }
}
pub fn with_format(mut self, format: Format) -> Self {
self.format = format;
self
}
pub fn with_pretty(mut self, pretty: bool) -> Self {
self.pretty = pretty;
self
}
pub fn with_indent(mut self, indent: u64) -> Self {
self.indent = indent;
self
}
pub fn with_base64(mut self, base64: bool) -> Self {
self.base64 = base64;
self
}
pub fn write<WriteT, SerializableT>(&self, value: &SerializableT, writer: &mut WriteT) -> Result<(), SerializeError>
where
WriteT: io::Write,
SerializableT: Serialize,
{
match self.format {
#[cfg(feature = "cbor")]
Format::CBOR => self.write_cbor(value, writer),
#[cfg(feature = "messagepack")]
Format::MessagePack => self.write_message_pack(value, writer),
#[cfg(feature = "yaml")]
Format::YAML => self.write_yaml(value, writer),
#[cfg(feature = "json")]
Format::JSON | Format::XJSON => self.write_json(value, writer),
#[cfg(feature = "xml")]
Format::XML => self.write_xml(value, writer),
#[cfg(not(all(
feature = "cbor",
feature = "messagepack",
feature = "yaml",
feature = "json",
feature = "xml",
)))]
_ => Err(SerializeError::UnsupportedFormat(self.format.clone())),
}
}
pub fn write_with_mode<WriteT, AnnotatedT>(
&self,
value: &Variant<AnnotatedT>,
mode: &SerializationMode,
writer: &mut WriteT,
) -> Result<(), SerializeError>
where
WriteT: io::Write,
AnnotatedT: Annotated + Clone + Default,
{
let value = value.modal(mode, self);
self.write(&value, writer)
}
pub fn write_modal<WriteT, AnnotatedT>(
&self,
value: &Variant<AnnotatedT>,
writer: &mut WriteT,
) -> Result<(), SerializeError>
where
WriteT: io::Write,
AnnotatedT: Annotated + Clone + Default,
{
match SerializationMode::for_format(&self.format) {
Some(serialization_mode) => self.write_with_mode(value, &serialization_mode, writer),
None => self.write(value, writer),
}
}
pub fn stringify<SerializableT>(&self, value: &SerializableT) -> Result<ByteString, SerializeError>
where
SerializableT: Serialize,
{
let mut writer = Vec::with_capacity(STRINGIFY_BUFFER_CAPACITY);
match self.clone().with_base64(true).write(value, &mut writer) {
Ok(_) => Ok(ByteString::try_from(writer)?),
Err(error) => Err(error),
}
}
pub fn stringify_with_mode<AnnotatedT>(
&self,
value: &Variant<AnnotatedT>,
mode: &SerializationMode,
) -> Result<ByteString, SerializeError>
where
AnnotatedT: Annotated + Clone + Default,
{
let value = value.modal(mode, self);
self.stringify(&value)
}
pub fn stringify_modal<AnnotatedT>(&self, value: &Variant<AnnotatedT>) -> Result<ByteString, SerializeError>
where
AnnotatedT: Annotated + Clone + Default,
{
match SerializationMode::for_format(&self.format) {
Some(serialization_mode) => self.stringify_with_mode(value, &serialization_mode),
None => self.stringify(value),
}
}
#[allow(dead_code)]
pub(crate) fn write_newline<WriteT>(writer: &mut WriteT) -> Result<(), SerializeError>
where
WriteT: io::Write,
{
writer.write(b"\n")?;
Ok(())
}
#[allow(dead_code)]
pub(crate) fn base64_writer<WriteT>(
writer: &mut WriteT,
) -> base64::write::EncoderWriter<'_, base64::engine::GeneralPurpose, &mut WriteT>
where
WriteT: io::Write,
{
base64::write::EncoderWriter::new(writer, &base64::engine::general_purpose::STANDARD)
}
}