pub(crate) mod cursor;
mod hash_stream;
#[cfg(test)]
mod tests;
use crate::{
error::InternalError,
serialize::{SerializeError, deserialize_bounded, serialize},
};
use serde::de::DeserializeOwned;
#[cfg(test)]
pub(in crate::db) use hash_stream::new_hash_sha256;
pub(in crate::db) use hash_stream::{
finalize_hash_sha256, new_hash_sha256_prefixed, write_hash_str_u32, write_hash_tag_u8,
write_hash_u32, write_hash_u64,
};
pub(crate) const MAX_ROW_BYTES: u32 = 4 * 1024 * 1024;
pub(in crate::db) const ROW_FORMAT_VERSION_CURRENT: u8 = 1;
#[cfg(test)]
type PersistedRowEnvelope = (u8, Vec<u8>);
#[cfg(test)]
pub(in crate::db) fn deserialize_row<T>(bytes: &[u8]) -> Result<T, InternalError>
where
T: DeserializeOwned,
{
let (format_version, payload) =
match deserialize_bounded::<PersistedRowEnvelope>(bytes, MAX_ROW_BYTES as usize) {
Ok(envelope) => envelope,
Err(SerializeError::DeserializeSizeLimitExceeded { len, max_bytes }) => {
return Err(InternalError::serialize_payload_decode_failed(
SerializeError::DeserializeSizeLimitExceeded { len, max_bytes },
"row",
));
}
Err(source) => {
return Err(InternalError::serialize_payload_decode_failed(
source, "row",
));
}
};
validate_row_format_version(format_version)?;
deserialize_persisted_payload(&payload, MAX_ROW_BYTES as usize, "row")
}
pub(in crate::db) fn serialize_row_payload(payload: Vec<u8>) -> Result<Vec<u8>, InternalError> {
serialize_row_payload_with_version(payload, ROW_FORMAT_VERSION_CURRENT)
}
pub(in crate::db) fn deserialize_persisted_payload<T>(
bytes: &[u8],
max_bytes: usize,
payload_label: &'static str,
) -> Result<T, InternalError>
where
T: DeserializeOwned,
{
deserialize_bounded(bytes, max_bytes)
.map_err(|source| InternalError::serialize_payload_decode_failed(source, payload_label))
}
pub(in crate::db) fn deserialize_protocol_payload<T>(
bytes: &[u8],
max_bytes: usize,
) -> Result<T, SerializeError>
where
T: DeserializeOwned,
{
deserialize_bounded(bytes, max_bytes)
}
#[cfg(test)]
fn validate_row_format_version(format_version: u8) -> Result<(), InternalError> {
if format_version == ROW_FORMAT_VERSION_CURRENT {
return Ok(());
}
Err(InternalError::serialize_incompatible_persisted_format(
format!(
"row format version {format_version} is unsupported by runtime version {ROW_FORMAT_VERSION_CURRENT}",
),
))
}
fn serialize_row_payload_with_version(
payload: Vec<u8>,
format_version: u8,
) -> Result<Vec<u8>, InternalError> {
serialize(&(format_version, payload)).map_err(InternalError::persisted_row_encode_failed)
}