Custom deserialize impl for ApisVec (#3471)

This commit is contained in:
Andrew Jones
2019-08-26 08:37:42 +01:00
committed by Bastian Köcher
parent da03850eed
commit aae31831fb
2 changed files with 54 additions and 6 deletions
+6 -4
View File
@@ -262,10 +262,12 @@ fn should_return_runtime_version() {
[\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\
[\"0xf78b278be53f454c\",1],[\"0xab3c0572291feb8b\",1]]}";
assert_eq!(
serde_json::to_string(&api.runtime_version(None.into()).unwrap()).unwrap(),
result,
);
let runtime_version = api.runtime_version(None.into()).unwrap();
let serialized = serde_json::to_string(&runtime_version).unwrap();
assert_eq!(serialized, result);
let deserialized: RuntimeVersion = serde_json::from_str(result).unwrap();
assert_eq!(deserialized, runtime_version);
}
#[test]
+48 -2
View File
@@ -96,7 +96,13 @@ pub struct RuntimeVersion {
pub impl_version: u32,
/// List of supported API "features" along with their versions.
#[cfg_attr(feature = "std", serde(serialize_with = "apis_serialize::serialize"))]
#[cfg_attr(
feature = "std",
serde(
serialize_with = "apis_serialize::serialize",
deserialize_with = "apis_serialize::deserialize",
)
)]
pub apis: ApisVec,
}
@@ -163,7 +169,7 @@ impl NativeVersion {
mod apis_serialize {
use super::*;
use impl_serde::serialize as bytes;
use serde::{Serializer, ser::SerializeTuple};
use serde::{Serializer, de, ser::SerializeTuple};
#[derive(Serialize)]
struct ApiId<'a>(
@@ -187,4 +193,44 @@ mod apis_serialize {
{
bytes::serialize(*apis, ser)
}
#[derive(Deserialize)]
struct ApiIdOwned(
#[serde(deserialize_with="deserialize_bytes")]
super::ApiId,
u32,
);
pub fn deserialize<'de, D>(deserializer: D) -> Result<ApisVec, D::Error> where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = ApisVec;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of api id and version tuples")
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> where
V: de::SeqAccess<'de>,
{
let mut apis = Vec::new();
while let Some(value) = visitor.next_element::<ApiIdOwned>()? {
apis.push((value.0, value.1));
}
Ok(apis.into())
}
}
deserializer.deserialize_seq(Visitor)
}
pub fn deserialize_bytes<'de, D>(d: D) -> Result<super::ApiId, D::Error> where
D: de::Deserializer<'de>
{
let bytes = bytes::deserialize_check_len(d, bytes::ExpectedLen::Exact(8))?;
let mut arr = [0; 8];
arr.copy_from_slice(&bytes);
Ok(arr)
}
}