use crate::transactions::types::HashDigest;
use digest::Digest;
use serde::{
de::{self, Visitor},
Deserialize,
Deserializer,
Serialize,
Serializer,
};
use std::fmt;
use tari_crypto::tari_utilities::{byte_array::*, hash::*, hex::*};
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct BulletRangeProof(pub Vec<u8>);
impl Hashable for BulletRangeProof {
fn hash(&self) -> Vec<u8> {
HashDigest::new().chain(&self.0).result().to_vec()
}
}
impl ByteArray for BulletRangeProof {
fn to_vec(&self) -> Vec<u8> {
self.0.clone()
}
fn from_vec(v: &Vec<u8>) -> Result<Self, ByteArrayError> {
Ok(BulletRangeProof { 0: v.clone() })
}
fn from_bytes(bytes: &[u8]) -> Result<Self, ByteArrayError> {
Ok(BulletRangeProof { 0: bytes.to_vec() })
}
fn as_bytes(&self) -> &[u8] {
&self.0
}
}
impl From<Vec<u8>> for BulletRangeProof {
fn from(v: Vec<u8>) -> Self {
BulletRangeProof(v)
}
}
impl fmt::Display for BulletRangeProof {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_hex())
}
}
impl Serialize for BulletRangeProof {
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 BulletRangeProof {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> {
struct RangeProofVisitor;
impl<'de> Visitor<'de> for RangeProofVisitor {
type Value = BulletRangeProof;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a bulletproof range proof in binary format")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<BulletRangeProof, E>
where E: de::Error {
BulletRangeProof::from_bytes(v).map_err(E::custom)
}
}
if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
BulletRangeProof::from_hex(&s).map_err(de::Error::custom)
} else {
deserializer.deserialize_bytes(RangeProofVisitor)
}
}
}