Define and implement PcdSerializable trait
This commit is contained in:
parent
f2a51aa6af
commit
132565e0b5
112
src/pcd.rs
112
src/pcd.rs
@ -27,6 +27,112 @@ use crate::{
|
||||
pub const PCD_VERSION: u8 = 1;
|
||||
pub(crate) const ZSTD_COMPRESSION_LEVEL: i32 = zstd::DEFAULT_COMPRESSION_LEVEL;
|
||||
|
||||
pub trait PcdSerializable {
|
||||
fn serialize_to_pcd(&self) -> Result<Vec<u8>>;
|
||||
fn deserialize_from_pcd(data: &[u8]) -> Result<Self> where Self: Sized;
|
||||
}
|
||||
|
||||
impl PcdSerializable for serde_json::Value {
|
||||
fn serialize_to_pcd(&self) -> Result<Vec<u8>> {
|
||||
let mut compressed = Vec::new();
|
||||
let mut encoder = zstd::stream::Encoder::new(&mut compressed, ZSTD_COMPRESSION_LEVEL)?;
|
||||
|
||||
encoder.write_all(&[PCD_VERSION])?;
|
||||
encoder.write_all(&[DataType::Json as u8])?;
|
||||
serde_json::to_writer(&mut encoder, self)?;
|
||||
encoder.finish()?;
|
||||
|
||||
Ok(compressed)
|
||||
}
|
||||
|
||||
fn deserialize_from_pcd(data: &[u8]) -> Result<Self> {
|
||||
let mut decompressed = Vec::new();
|
||||
zstd::stream::copy_decode(data, &mut decompressed)?;
|
||||
|
||||
if decompressed.len() < 3 {
|
||||
return Err(Error::msg("Invalid data: too short"));
|
||||
}
|
||||
|
||||
let version = decompressed[0];
|
||||
let data_type = DataType::try_from(decompressed[1])?;
|
||||
|
||||
match (version, data_type) {
|
||||
(PCD_VERSION, DataType::Json) => {
|
||||
let json_bytes = &decompressed[2..];
|
||||
let json_string = String::from_utf8(json_bytes.to_vec())?;
|
||||
Ok(serde_json::from_str(&json_string)?)
|
||||
},
|
||||
_ => Err(Error::msg("Invalid version or data type"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PcdSerializable for FileBlob {
|
||||
fn serialize_to_pcd(&self) -> Result<Vec<u8>> {
|
||||
let mut compressed = Vec::new();
|
||||
let mut encoder = zstd::stream::Encoder::new(&mut compressed, ZSTD_COMPRESSION_LEVEL)?;
|
||||
|
||||
encoder.write_all(&[PCD_VERSION])?;
|
||||
encoder.write_all(&[DataType::FileBlob as u8])?;
|
||||
|
||||
let type_len = self.r#type.as_bytes().len() as u8;
|
||||
encoder.write_all(&[type_len])?;
|
||||
encoder.write_all(self.r#type.as_bytes())?;
|
||||
encoder.write_all(&self.data)?;
|
||||
|
||||
encoder.finish()?;
|
||||
Ok(compressed)
|
||||
}
|
||||
|
||||
fn deserialize_from_pcd(data: &[u8]) -> Result<Self> {
|
||||
let mut decompressed = Vec::new();
|
||||
zstd::stream::copy_decode(data, &mut decompressed)?;
|
||||
|
||||
if decompressed.len() < 4 {
|
||||
return Err(Error::msg("Invalid data: too short"));
|
||||
}
|
||||
|
||||
let version = decompressed[0];
|
||||
let data_type = DataType::try_from(decompressed[1])?;
|
||||
|
||||
match (version, data_type) {
|
||||
(PCD_VERSION, DataType::FileBlob) => {
|
||||
let type_len = decompressed[2] as usize;
|
||||
let type_str = String::from_utf8(decompressed[3..3+type_len].to_vec())?;
|
||||
let data = decompressed[3+type_len..].to_vec();
|
||||
|
||||
Ok(FileBlob { r#type: type_str, data })
|
||||
},
|
||||
_ => Err(Error::msg("Invalid version or data type"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DataType {
|
||||
FileBlob = 0,
|
||||
Json = 1,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for DataType {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self> {
|
||||
match value {
|
||||
0 => Ok(DataType::FileBlob),
|
||||
1 => Ok(DataType::Json),
|
||||
_ => return Err(Error::msg(format!("Unknown data type: {}", value))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct FileBlob {
|
||||
pub r#type: String,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Tsify)]
|
||||
#[tsify(into_wasm_abi, from_wasm_abi)]
|
||||
pub struct Member {
|
||||
@ -110,12 +216,6 @@ impl Member {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct FileBlob {
|
||||
pub r#type: String,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Tsify)]
|
||||
#[tsify(into_wasm_abi, from_wasm_abi)]
|
||||
pub struct Pcd(BTreeMap<String, Vec<u8>>);
|
||||
|
Loading…
x
Reference in New Issue
Block a user