use std::collections::VecDeque;
use byteorder::BigEndian;
use byteorder::WriteBytesExt;
use serde::ser;
use serde::ser::Serialize;
use serde::ser::SerializeMap;
use serde::ser::SerializeSeq;
use super::constants::*;
use super::jentry::JEntry;
use crate::RawJsonb;
use crate::extension::ExtensionValue;
use crate::number::Number;
use crate::value::Object;
use crate::value::Value;
impl Serialize for RawJsonb<'_> {
#[inline]
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut index = 0;
let (header_type, header_len) = self
.read_header(index)
.map_err(|e| ser::Error::custom(format!("{e}")))?;
index += 4;
match header_type {
SCALAR_CONTAINER_TAG => {
let jentry = self
.read_jentry(index)
.map_err(|e| ser::Error::custom(format!("{e}")))?;
index += 4;
let payload_start = index;
let payload_end = index + jentry.length as usize;
match jentry.type_code {
NULL_TAG => serializer.serialize_unit(),
TRUE_TAG => serializer.serialize_bool(true),
FALSE_TAG => serializer.serialize_bool(false),
NUMBER_TAG => {
let num = Number::decode(&self.data[payload_start..payload_end])
.map_err(|e| ser::Error::custom(format!("{e}")))?;
num.serialize(serializer)
}
STRING_TAG => {
let s = unsafe {
std::str::from_utf8_unchecked(&self.data[payload_start..payload_end])
};
serializer.serialize_str(s)
}
EXTENSION_TAG => {
let val = ExtensionValue::decode(&self.data[payload_start..payload_end])
.map_err(|e| ser::Error::custom(format!("{e}")))?;
let s = format!("{}", val);
serializer.serialize_str(&s)
}
CONTAINER_TAG => {
Err(ser::Error::custom("Invalid jsonb".to_string()))
}
_ => Err(ser::Error::custom("Invalid jsonb".to_string())),
}
}
ARRAY_CONTAINER_TAG => {
let mut serialize_seq = serializer.serialize_seq(Some(header_len))?;
let mut payload_start = index + 4 * header_len;
for _ in 0..header_len {
let jentry = self
.read_jentry(index)
.map_err(|e| ser::Error::custom(format!("{e}")))?;
index += 4;
let payload_end = payload_start + jentry.length as usize;
match jentry.type_code {
NULL_TAG => serialize_seq.serialize_element(&())?,
TRUE_TAG => serialize_seq.serialize_element(&true)?,
FALSE_TAG => serialize_seq.serialize_element(&false)?,
NUMBER_TAG => {
let num = Number::decode(&self.data[payload_start..payload_end])
.map_err(|e| ser::Error::custom(format!("{e}")))?;
serialize_seq.serialize_element(&num)?;
}
STRING_TAG => {
let s = unsafe {
std::str::from_utf8_unchecked(
&self.data[payload_start..payload_end],
)
};
serialize_seq.serialize_element(&s)?;
}
EXTENSION_TAG => {
let val =
ExtensionValue::decode(&self.data[payload_start..payload_end])
.map_err(|e| ser::Error::custom(format!("{e}")))?;
let s = format!("{}", val);
serialize_seq.serialize_element(&s)?;
}
CONTAINER_TAG => {
let inner_raw_jsonb =
RawJsonb::new(&self.data[payload_start..payload_end]);
serialize_seq.serialize_element(&inner_raw_jsonb)?;
}
_ => {
return Err(ser::Error::custom("Invalid jsonb".to_string()));
}
}
payload_start = payload_end;
}
serialize_seq.end()
}
OBJECT_CONTAINER_TAG => {
let mut serialize_map = serializer.serialize_map(Some(header_len))?;
let mut keys = VecDeque::with_capacity(header_len);
let mut payload_start = index + 8 * header_len;
for _ in 0..header_len {
let jentry = self
.read_jentry(index)
.map_err(|e| ser::Error::custom(format!("{e}")))?;
index += 4;
let payload_end = payload_start + jentry.length as usize;
match jentry.type_code {
STRING_TAG => {
let s = unsafe {
std::str::from_utf8_unchecked(
&self.data[payload_start..payload_end],
)
};
keys.push_back(s);
}
_ => {
return Err(ser::Error::custom("Invalid jsonb".to_string()));
}
}
payload_start = payload_end;
}
for _ in 0..header_len {
let jentry = self
.read_jentry(index)
.map_err(|e| ser::Error::custom(format!("{e}")))?;
index += 4;
let payload_end = payload_start + jentry.length as usize;
let k = keys.pop_front().unwrap();
match jentry.type_code {
NULL_TAG => serialize_map.serialize_entry(&k, &())?,
TRUE_TAG => serialize_map.serialize_entry(&k, &true)?,
FALSE_TAG => serialize_map.serialize_entry(&k, &false)?,
NUMBER_TAG => {
let num = Number::decode(&self.data[payload_start..payload_end])
.map_err(|e| ser::Error::custom(format!("{e}")))?;
serialize_map.serialize_entry(&k, &num)?;
}
STRING_TAG => {
let s = unsafe {
std::str::from_utf8_unchecked(
&self.data[payload_start..payload_end],
)
};
serialize_map.serialize_entry(&k, &s)?;
}
EXTENSION_TAG => {
let val =
ExtensionValue::decode(&self.data[payload_start..payload_end])
.map_err(|e| ser::Error::custom(format!("{e}")))?;
let s = format!("{}", val);
serialize_map.serialize_entry(&k, &s)?;
}
CONTAINER_TAG => {
let inner_raw_jsonb =
RawJsonb::new(&self.data[payload_start..payload_end]);
serialize_map.serialize_entry(&k, &inner_raw_jsonb)?;
}
_ => {
return Err(ser::Error::custom("Invalid jsonb".to_string()));
}
}
payload_start = payload_end;
}
serialize_map.end()
}
_ => Err(ser::Error::custom("Invalid jsonb".to_string())),
}
}
}
struct BaseEncoder<'a> {
buf: &'a mut Vec<u8>,
}
impl<'a> BaseEncoder<'a> {
fn new(buf: &'a mut Vec<u8>) -> Self {
Self { buf }
}
fn reserve_jentries(&mut self, len: usize) -> usize {
let old_len = self.buf.len();
let new_len = old_len + len;
self.buf.resize(new_len, 0);
old_len
}
fn replace_jentry(&mut self, jentry: JEntry, jentry_index: &mut usize) {
let jentry_bytes = jentry.encoded().to_be_bytes();
for (i, b) in jentry_bytes.iter().enumerate() {
self.buf[*jentry_index + i] = *b;
}
*jentry_index += 4;
}
fn encode_scalar_header(&mut self) -> (usize, usize) {
let header = SCALAR_CONTAINER_TAG;
self.buf.write_u32::<BigEndian>(header).unwrap();
let scalar_len = 4 + 4;
let jentry_index = self.reserve_jentries(4);
(scalar_len, jentry_index)
}
fn encode_array_header(&mut self, len: usize) -> (usize, usize) {
let header = ARRAY_CONTAINER_TAG | len as u32;
self.buf.write_u32::<BigEndian>(header).unwrap();
let array_len = 4 + len * 4;
let jentry_index = self.reserve_jentries(len * 4);
(array_len, jentry_index)
}
fn encode_object_header(&mut self, len: usize) -> (usize, usize) {
let header = OBJECT_CONTAINER_TAG | len as u32;
self.buf.write_u32::<BigEndian>(header).unwrap();
let object_len = 4 + len * 8;
let jentry_index = self.reserve_jentries(len * 8);
(object_len, jentry_index)
}
}
pub struct Encoder<'a> {
base_encoder: BaseEncoder<'a>,
}
impl<'a> Encoder<'a> {
pub(crate) fn new(buf: &'a mut Vec<u8>) -> Self {
let base_encoder = BaseEncoder::new(buf);
Self { base_encoder }
}
pub(crate) fn encode(&mut self, value: &Value<'a>) {
match value {
Value::Array(array) => self.encode_array(array),
Value::Object(obj) => self.encode_object(obj),
_ => self.encode_scalar(value),
};
}
fn encode_scalar(&mut self, value: &Value<'a>) -> usize {
let (mut scalar_len, mut jentry_index) = self.base_encoder.encode_scalar_header();
let jentry = self.encode_value(value);
scalar_len += jentry.length as usize;
self.base_encoder.replace_jentry(jentry, &mut jentry_index);
scalar_len
}
fn encode_array(&mut self, values: &[Value<'a>]) -> usize {
let (mut array_len, mut jentry_index) = self.base_encoder.encode_array_header(values.len());
for value in values.iter() {
let jentry = self.encode_value(value);
array_len += jentry.length as usize;
self.base_encoder.replace_jentry(jentry, &mut jentry_index);
}
array_len
}
fn encode_object(&mut self, obj: &Object<'a>) -> usize {
let (mut object_len, mut jentry_index) = self.base_encoder.encode_object_header(obj.len());
for key in obj.keys() {
let len = key.len();
object_len += len;
self.base_encoder.buf.extend_from_slice(key.as_bytes());
let jentry = JEntry::make_string_jentry(len);
self.base_encoder.replace_jentry(jentry, &mut jentry_index);
}
for value in obj.values() {
let jentry = self.encode_value(value);
object_len += jentry.length as usize;
self.base_encoder.replace_jentry(jentry, &mut jentry_index);
}
object_len
}
fn encode_value(&mut self, value: &Value<'a>) -> JEntry {
let old_off = self.base_encoder.buf.len();
match value {
Value::Null => JEntry::make_null_jentry(),
Value::Bool(v) => {
if *v {
JEntry::make_true_jentry()
} else {
JEntry::make_false_jentry()
}
}
Value::Number(v) => {
let _ = v.compact_encode(&mut self.base_encoder.buf).unwrap();
let len = self.base_encoder.buf.len() - old_off;
JEntry::make_number_jentry(len)
}
Value::String(s) => {
let len = s.len();
self.base_encoder
.buf
.extend_from_slice(s.as_ref().as_bytes());
JEntry::make_string_jentry(len)
}
Value::Binary(v) => {
let val = ExtensionValue::Binary(v);
let _ = val.compact_encode(&mut self.base_encoder.buf).unwrap();
let len = self.base_encoder.buf.len() - old_off;
JEntry::make_extension_jentry(len)
}
Value::Date(v) => {
let val = ExtensionValue::Date(v.clone());
let _ = val.compact_encode(&mut self.base_encoder.buf).unwrap();
let len = self.base_encoder.buf.len() - old_off;
JEntry::make_extension_jentry(len)
}
Value::Timestamp(v) => {
let val = ExtensionValue::Timestamp(v.clone());
let _ = val.compact_encode(&mut self.base_encoder.buf).unwrap();
let len = self.base_encoder.buf.len() - old_off;
JEntry::make_extension_jentry(len)
}
Value::TimestampTz(v) => {
let val = ExtensionValue::TimestampTz(v.clone());
let _ = val.compact_encode(&mut self.base_encoder.buf).unwrap();
let len = self.base_encoder.buf.len() - old_off;
JEntry::make_extension_jentry(len)
}
Value::Interval(v) => {
let val = ExtensionValue::Interval(v.clone());
let _ = val.compact_encode(&mut self.base_encoder.buf).unwrap();
let len = self.base_encoder.buf.len() - old_off;
JEntry::make_extension_jentry(len)
}
Value::Array(array) => {
let len = self.encode_array(array);
JEntry::make_container_jentry(len)
}
Value::Object(obj) => {
let len = self.encode_object(obj);
JEntry::make_container_jentry(len)
}
}
}
}