feat(common): add serde to Timestamp

This commit is contained in:
nazeh
2024-08-26 14:24:37 +03:00
parent 620e2ad2ee
commit ab7c005d67
2 changed files with 74 additions and 0 deletions

View File

@@ -19,3 +19,6 @@ crypto_secretbox = { version = "0.1.1", features = ["std"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3.69"
[dev-dependencies]
postcard = "1.0.8"

View File

@@ -6,6 +6,12 @@ use std::{
sync::Mutex,
};
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeTuple,
Deserialize, Deserializer, Serialize, Serializer,
};
use once_cell::sync::Lazy;
use rand::Rng;
@@ -173,6 +179,58 @@ pub fn system_time() -> u64 {
* 1000
}
// === Serde ===
impl Serialize for Timestamp {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// Convert u64 to 8 bytes in Big-Endian format
let mut tup = serializer.serialize_tuple(8)?;
for byte in self.to_bytes() {
tup.serialize_element(&byte)?;
}
tup.end()
}
}
impl<'de> Deserialize<'de> for Timestamp {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct TimestampVisitor;
impl<'de> Visitor<'de> for TimestampVisitor {
type Value = Timestamp;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a tuple of 8 bytes")
}
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut bytes = [0u8; 8];
for i in 0..8 {
bytes[i] = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
}
Ok(Timestamp::from(bytes))
}
}
deserializer.deserialize_tuple(8, TimestampVisitor)
}
}
#[derive(thiserror::Error, Debug)]
pub enum TimestampError {
#[error("Invalid bytes length, Timestamp should be encoded as 8 bytes, got {0}")]
@@ -237,4 +295,17 @@ mod tests {
assert_eq!(decoded, timestamp)
}
#[test]
fn serde() {
let timestamp = Timestamp::now();
let serialized = postcard::to_allocvec(&timestamp).unwrap();
assert_eq!(serialized, timestamp.to_bytes());
let deserialized: Timestamp = postcard::from_bytes(&serialized).unwrap();
assert_eq!(deserialized, timestamp);
}
}