Source code

Revision control

Copy as Markdown

Other Tools

use std::fmt::Write as _;
use crate::{utils, Date, Decimal, Integer, KeyRef, RefBareItem, StringRef, TokenRef};
pub(crate) struct Serializer;
impl Serializer {
pub(crate) fn serialize_bare_item<'b>(value: impl Into<RefBareItem<'b>>, output: &mut String) {
match value.into() {
RefBareItem::Boolean(value) => Self::serialize_bool(value, output),
RefBareItem::String(value) => Self::serialize_string(value, output),
RefBareItem::ByteSequence(value) => Self::serialize_byte_sequence(value, output),
RefBareItem::Token(value) => Self::serialize_token(value, output),
RefBareItem::Integer(value) => Self::serialize_integer(value, output),
RefBareItem::Decimal(value) => Self::serialize_decimal(value, output),
RefBareItem::Date(value) => Self::serialize_date(value, output),
RefBareItem::DisplayString(value) => Self::serialize_display_string(value, output),
}
}
pub(crate) fn serialize_parameter<'b>(
name: &KeyRef,
value: impl Into<RefBareItem<'b>>,
output: &mut String,
) {
output.push(';');
Self::serialize_key(name, output);
let value = value.into();
if value != RefBareItem::Boolean(true) {
output.push('=');
Self::serialize_bare_item(value, output);
}
}
pub(crate) fn serialize_key(input_key: &KeyRef, output: &mut String) {
output.push_str(input_key.as_str());
}
pub(crate) fn serialize_integer(value: Integer, output: &mut String) {
write!(output, "{value}").unwrap();
}
pub(crate) fn serialize_decimal(value: Decimal, output: &mut String) {
write!(output, "{value}").unwrap();
}
pub(crate) fn serialize_string(value: &StringRef, output: &mut String) {
output.push('"');
for char in value.as_str().chars() {
if char == '\\' || char == '"' {
output.push('\\');
}
output.push(char);
}
output.push('"');
}
pub(crate) fn serialize_token(value: &TokenRef, output: &mut String) {
output.push_str(value.as_str());
}
pub(crate) fn serialize_byte_sequence(value: &[u8], output: &mut String) {
output.push(':');
base64::Engine::encode_string(&utils::BASE64, value, output);
output.push(':');
}
pub(crate) fn serialize_bool(value: bool, output: &mut String) {
output.push_str(if value { "?1" } else { "?0" });
}
pub(crate) fn serialize_date(value: Date, output: &mut String) {
write!(output, "{value}").unwrap();
}
pub(crate) fn serialize_display_string(value: &str, output: &mut String) {
output.push_str(r#"%""#);
for c in value.bytes() {
match c {
b'%' | b'"' | 0x00..=0x1f | 0x7f..=0xff => {
output.push('%');
output.push(char::from_digit((u32::from(c) >> 4) & 0xf, 16).unwrap());
output.push(char::from_digit(u32::from(c) & 0xf, 16).unwrap());
}
_ => output.push(c as char),
}
}
output.push('"');
}
}