use super::*;
pub fn from_single_object_slice<'a, T>(slice: &'a [u8], schema: &Schema) -> Result<T, de::DeError>
where
T: serde::Deserialize<'a>,
{
let header: &[u8; 10] = slice
.get(0..10)
.ok_or_else(|| de::DeError::new("Slice is too short for single object encoding header"))?
.try_into()
.unwrap();
check_header(header, schema)?;
from_datum_slice(&slice[10..], schema)
}
pub fn from_single_object_reader<R, T>(mut reader: R, schema: &Schema) -> Result<T, de::DeError>
where
T: serde::de::DeserializeOwned,
R: std::io::BufRead,
{
let mut header_buf = [0u8; 10];
reader
.read_exact(&mut header_buf)
.map_err(de::DeError::io)?;
check_header(&header_buf, schema)?;
from_datum_reader(reader, schema)
}
fn check_header(slice: &[u8; 10], schema: &Schema) -> Result<(), de::DeError> {
if slice[0..2] != [0xC3, 0x01] {
return Err(de::DeError::new(
"Single object slice does not respect C3 01 header",
));
}
if &slice[2..10] != schema.rabin_fingerprint() {
return Err(de::DeError::new(
"Single object encoding fingerprint header does not match with schema fingerprint",
));
}
Ok(())
}
pub fn to_single_object<T, W>(
value: &T,
mut writer: W,
serializer_config: &mut ser::SerializerConfig<'_>,
) -> Result<W, ser::SerError>
where
T: serde::Serialize + ?Sized,
W: std::io::Write,
{
writer.write_all(&[0xC3, 0x01]).map_err(ser::SerError::io)?;
writer
.write_all(serializer_config.schema().rabin_fingerprint())
.map_err(ser::SerError::io)?;
to_datum(value, writer, serializer_config)
}
pub fn to_single_object_vec<T>(
value: &T,
serializer_config: &mut ser::SerializerConfig<'_>,
) -> Result<Vec<u8>, ser::SerError>
where
T: serde::Serialize + ?Sized,
{
let mut buf = Vec::new();
to_single_object(value, &mut buf, serializer_config)?;
Ok(buf)
}