From 9509c9125f985685fb9ec8ed4b968514c6c6e617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Frosteg=C3=A5rd?= Date: Sat, 9 May 2020 13:28:01 +0200 Subject: [PATCH] aquatic_ws: add custom deserializer for 20 ascii byte strings --- aquatic_ws/src/lib/protocol.rs | 57 +++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/aquatic_ws/src/lib/protocol.rs b/aquatic_ws/src/lib/protocol.rs index 9060fda..fb9bbad 100644 --- a/aquatic_ws/src/lib/protocol.rs +++ b/aquatic_ws/src/lib/protocol.rs @@ -1,23 +1,66 @@ use hashbrown::HashMap; -use serde::{Serialize, Deserialize}; +use serde::{Serialize, Deserialize, Deserializer, de::Visitor}; + + +struct TwentyAsciiBytesVisitor; + +impl<'de> Visitor<'de> for TwentyAsciiBytesVisitor { + type Value = [u8; 20]; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("string consisting of 20 bytes") + } + + fn visit_str(self, value: &str) -> Result + where + E: ::serde::de::Error, + { + let mut arr = [0u8; 20]; + + let bytes = value.as_bytes(); + + if value.is_ascii() && bytes.len() == 20 { + arr.copy_from_slice(&bytes); + + Ok(arr) + } else { + Err(E::custom(format!("not 20 ascii bytes: {}", value))) + } + } +} + + +fn deserialize_20_ascii_bytes<'de, D>( + deserializer: D +) -> Result<[u8; 20], D::Error> + where D: Deserializer<'de> +{ + deserializer.deserialize_any(TwentyAsciiBytesVisitor) +} -/// FIXME: This is really just string with 20 length #[derive(Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)] #[serde(transparent)] -pub struct PeerId(pub [u8; 20]); +pub struct PeerId( + #[serde(deserialize_with = "deserialize_20_ascii_bytes")] + pub [u8; 20] +); -/// FIXME: This is really just string with 20 length #[derive(Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)] #[serde(transparent)] -pub struct InfoHash(pub [u8; 20]); +pub struct InfoHash( + #[serde(deserialize_with = "deserialize_20_ascii_bytes")] + pub [u8; 20] +); -/// FIXME: This is really just string with 20 length #[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(transparent)] -pub struct OfferId(pub [u8; 20]); +pub struct OfferId( + #[serde(deserialize_with = "deserialize_20_ascii_bytes")] + pub [u8; 20] +); /// Some kind of nested structure from https://www.npmjs.com/package/simple-peer