use alloc::string::String;
use core::fmt;
use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
de::{self, Visitor},
};
use tari_utilities::{byte_array::ByteArray, hex::Hex};
use zeroize::Zeroize;
use crate::ristretto::{RistrettoPublicKey, RistrettoSecretKey};
impl<'de> Deserialize<'de> for RistrettoPublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> {
struct RistrettoPubKeyVisitor;
impl Visitor<'_> for RistrettoPubKeyVisitor {
type Value = RistrettoPublicKey;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a public key in binary format")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<RistrettoPublicKey, E>
where E: de::Error {
RistrettoPublicKey::from_canonical_bytes(v).map_err(E::custom)
}
}
if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
RistrettoPublicKey::from_hex(&s).map_err(de::Error::custom)
} else {
deserializer.deserialize_bytes(RistrettoPubKeyVisitor)
}
}
}
impl Serialize for RistrettoPublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
if serializer.is_human_readable() {
self.to_hex().serialize(serializer)
} else {
serializer.serialize_bytes(self.as_bytes())
}
}
}
impl<'de> Deserialize<'de> for RistrettoSecretKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> {
struct RistrettoVisitor;
impl Visitor<'_> for RistrettoVisitor {
type Value = RistrettoSecretKey;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a secret key in binary format")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<RistrettoSecretKey, E>
where E: de::Error {
RistrettoSecretKey::from_canonical_bytes(v).map_err(E::custom)
}
}
if deserializer.is_human_readable() {
let mut s = String::deserialize(deserializer)?;
let v = RistrettoSecretKey::from_hex(&s).map_err(de::Error::custom);
s.zeroize();
v
} else {
deserializer.deserialize_bytes(RistrettoVisitor)
}
}
}
impl Serialize for RistrettoSecretKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
if serializer.is_human_readable() {
let mut s = self.to_hex();
let result = s.serialize(serializer);
s.zeroize();
result
} else {
serializer.serialize_bytes(self.as_bytes())
}
}
}