use core::convert::{TryFrom, TryInto};
use core::fmt;
use core::marker::PhantomData;
use serde::de::{Deserializer, Error, SeqAccess, Visitor};
use serde::ser::{SerializeTuple, Serializer};
use serde::{Deserialize, Serialize};
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub struct PortalKeyExchange([u8; 33]);
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub struct PortalConfirmation(pub [u8; 42]);
struct ArrayVisitor<T> {
element: PhantomData<T>,
}
impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor<[T; N]>
where
T: Default + Copy + Deserialize<'de>,
{
type Value = [T; N];
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "an array of length {}", N)
}
fn visit_seq<A>(self, mut seq: A) -> Result<[T; N], A::Error>
where
A: SeqAccess<'de>,
{
let mut arr = [T::default(); N];
for (i, item) in arr.iter_mut().enumerate().take(N) {
*item = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(i, &self))?;
}
Ok(arr)
}
}
impl<'de> Deserialize<'de> for PortalKeyExchange {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let visitor = ArrayVisitor {
element: PhantomData,
};
let res =
deserializer.deserialize_tuple(std::mem::size_of::<PortalKeyExchange>(), visitor)?;
Ok(Self(res))
}
}
impl Serialize for PortalKeyExchange {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_tuple(self.0.len())?;
for elem in &self.0[..] {
seq.serialize_element(elem)?;
}
seq.end()
}
}
#[allow(clippy::from_over_into)]
impl<'a> Into<&'a [u8]> for &'a PortalKeyExchange {
fn into(self) -> &'a [u8] {
&self.0
}
}
impl TryFrom<Vec<u8>> for PortalKeyExchange {
type Error = &'static str;
fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
Ok(Self(
v.try_into()
.or(Err("Cannot convert into PortalKeyExchange"))?,
))
}
}
impl<'de> Deserialize<'de> for PortalConfirmation {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let visitor = ArrayVisitor {
element: PhantomData,
};
let res =
deserializer.deserialize_tuple(std::mem::size_of::<PortalConfirmation>(), visitor)?;
Ok(Self(res))
}
}
impl Serialize for PortalConfirmation {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_tuple(self.0.len())?;
for elem in &self.0[..] {
seq.serialize_element(elem)?;
}
seq.end()
}
}