Skip to content

Commit

Permalink
Support serde_with
Browse files Browse the repository at this point in the history
  • Loading branch information
survived committed Mar 3, 2022
1 parent f403882 commit d040be6
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 52 deletions.
73 changes: 72 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion delivery/trusted-delivery/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rand = "0.8"
crypto-mac = "0.11"

serde = { version = "1", features = ["derive"] }
serde_with = "1.12"
hex = { version = "0.4", features = ["serde"] }
phantom-type = "0.3"
never = "0.1"
Expand All @@ -32,4 +33,4 @@ rand-v7 = { package = "rand", version = "0.7.3", optional = true }

[features]
default = ["default-crypto-suite"]
default-crypto-suite = ["hkdf", "hmac", "sha2", "aes-gcm", "aead", "x25519-dalek", "ed25519-dalek", "rand-v7"]
default-crypto-suite = ["hkdf", "hmac", "sha2", "aes-gcm", "aead", "x25519-dalek", "ed25519-dalek", "rand-v7"]
120 changes: 70 additions & 50 deletions delivery/trusted-delivery/core/src/crypto/serde.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;

use generic_array::GenericArray;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserializer, Serializer};

use super::Serializable;

Expand Down Expand Up @@ -55,62 +55,82 @@ where
}
}

/// Wraps [`Serializable`] and implements [serde] traits: [`Serialize`] and [`Deserialize`]
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct Serde<S>(pub S);
pub struct SerdeAs;

impl<S: Serializable> Serialize for Serde<S> {
fn serialize<M>(&self, serializer: M) -> Result<M::Ok, M::Error>
impl<T: Serializable> serde_with::SerializeAs<T> for SerdeAs {
fn serialize_as<S>(thing: &T, serializer: S) -> Result<S::Ok, S::Error>
where
M: serde::ser::Serializer,
S: Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_str(&hex::encode(self.0.to_bytes()))
} else {
serializer.serialize_bytes(&self.0.to_bytes())
}
serialize(thing, serializer)
}
}

impl<'de, S: Serializable> Deserialize<'de> for Serde<S> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
impl<'de, T: Serializable> serde_with::DeserializeAs<'de, T> for SerdeAs {
fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
where
D: serde::de::Deserializer<'de>,
D: Deserializer<'de>,
{
use std::marker::PhantomData;

use serde::de::{Error, Visitor};

struct TheVisitor<S>(PhantomData<S>);
impl<'de, S: Serializable> Visitor<'de> for TheVisitor<S> {
type Value = S;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", S::NAME)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
let mut bytes = GenericArray::<u8, S::Size>::default();
hex::decode_to_slice(v, &mut bytes).map_err(|_| E::custom("invalid hex string"))?;
S::from_bytes(&bytes).map_err(E::custom)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
S::from_bytes(v).map_err(E::custom)
}
}

if deserializer.is_human_readable() {
deserializer
.deserialize_str(TheVisitor(PhantomData))
.map(Self)
} else {
deserializer
.deserialize_bytes(TheVisitor(PhantomData))
.map(Self)
}
deserialize(deserializer)
}
}

// /// Wraps [`Serializable`] and implements [serde] traits: [`Serialize`] and [`Deserialize`]
// #[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
// pub struct Serde<S>(pub S);
//
// impl<S: Serializable> Serialize for Serde<S> {
// fn serialize<M>(&self, serializer: M) -> Result<M::Ok, M::Error>
// where
// M: serde::ser::Serializer,
// {
// if serializer.is_human_readable() {
// serializer.serialize_str(&hex::encode(self.0.to_bytes()))
// } else {
// serializer.serialize_bytes(&self.0.to_bytes())
// }
// }
// }
//
// impl<'de, S: Serializable> Deserialize<'de> for Serde<S> {
// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
// where
// D: serde::de::Deserializer<'de>,
// {
// use std::marker::PhantomData;
//
// use serde::de::{Error, Visitor};
//
// struct TheVisitor<S>(PhantomData<S>);
// impl<'de, S: Serializable> Visitor<'de> for TheVisitor<S> {
// type Value = S;
// fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
// write!(f, "{}", S::NAME)
// }
// fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
// where
// E: Error,
// {
// let mut bytes = GenericArray::<u8, S::Size>::default();
// hex::decode_to_slice(v, &mut bytes).map_err(|_| E::custom("invalid hex string"))?;
// S::from_bytes(&bytes).map_err(E::custom)
// }
// fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
// where
// E: Error,
// {
// S::from_bytes(v).map_err(E::custom)
// }
// }
//
// if deserializer.is_human_readable() {
// deserializer
// .deserialize_str(TheVisitor(PhantomData))
// .map(Self)
// } else {
// deserializer
// .deserialize_bytes(TheVisitor(PhantomData))
// .map(Self)
// }
// }
// }

0 comments on commit d040be6

Please sign in to comment.