use core::fmt;
use std::{format, vec::Vec};
use serde::{de, ser};
use serde_bytes::ByteBuf;
use super::Cid;
pub const CID_SERDE_PRIVATE_IDENTIFIER: &str = "$__private__serde__identifier__for__cid";
impl ser::Serialize for Cid {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
let raw = self.as_bytes();
let mut bytes = vec![0u8; 1 + raw.len()];
bytes[1..].copy_from_slice(raw);
let value = ByteBuf::from(bytes);
serializer.serialize_newtype_struct(CID_SERDE_PRIVATE_IDENTIFIER, &value)
}
}
pub struct BytesToCidVisitor;
impl<'de> de::Visitor<'de> for BytesToCidVisitor {
type Value = Cid;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "a valid CID in bytes")
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
Cid::from_bytes_raw(value)
.map_err(|err| de::Error::custom(format!("Failed to deserialize CID: {err}")))
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut bytes = Vec::new();
while let Some(byte) = seq.next_element()? {
bytes.push(byte);
}
Cid::from_bytes_raw(&bytes)
.map_err(|err| de::Error::custom(format!("Failed to deserialize CID: {err}")))
}
}
impl<'de> de::Deserialize<'de> for Cid {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct MainEntryVisitor;
impl<'de> de::Visitor<'de> for MainEntryVisitor {
type Value = Cid;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "a valid CID in bytes, wrapped in an newtype struct")
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_bytes(BytesToCidVisitor)
}
}
deserializer.deserialize_newtype_struct(CID_SERDE_PRIVATE_IDENTIFIER, MainEntryVisitor)
}
}