pub mod parse {
use std::{
fmt::{self, Display},
marker::PhantomData,
str::{from_utf8, FromStr},
};
use serde::{
de::{self, Unexpected, Visitor},
Deserializer, Serializer,
};
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: Display,
S: Serializer,
{
serializer.serialize_bytes(value.to_string().as_bytes())
}
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: FromStr,
T::Err: Display,
D: Deserializer<'de>,
{
struct ParseVisitor<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for ParseVisitor<T>
where
T: FromStr,
T::Err: Display,
{
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string or integer")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
v.parse().map_err(E::custom)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
match from_utf8(v) {
Ok(str) => self.visit_str(str),
Err(_) => Err(E::invalid_value(Unexpected::Bytes(v), &self)),
}
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_str(&v.to_string())
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_str(&v.to_string())
}
}
deserializer.deserialize_any(ParseVisitor(PhantomData))
}
}
pub mod str {
use std::{fmt, str::from_utf8};
use serde::{
de::{self, Unexpected, Visitor},
Deserializer, Serializer,
};
pub fn serialize<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(value.as_bytes())
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<&'de str, D::Error>
where
D: Deserializer<'de>,
{
struct StrVisitor;
impl<'de> Visitor<'de> for StrVisitor {
type Value = &'de str;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a borrowed string")
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(v)
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
from_utf8(v).map_err(|_| E::invalid_value(Unexpected::Bytes(v), &self))
}
}
deserializer.deserialize_any(StrVisitor)
}
}
pub mod tuple_map {
use std::{collections::HashMap, hash::Hash, marker::PhantomData};
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeSeq,
Deserialize, Deserializer, Serialize, Serializer,
};
pub fn serialize<K, V, S>(value: &HashMap<K, V>, serializer: S) -> Result<S::Ok, S::Error>
where
K: Serialize,
V: Serialize,
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(value.len()))?;
for entry in value {
seq.serialize_element(&entry)?;
}
seq.end()
}
pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result<HashMap<K, V>, D::Error>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
D: Deserializer<'de>,
{
struct MapVisitor<K, V>(PhantomData<K>, PhantomData<V>);
impl<K, V> Default for MapVisitor<K, V> {
fn default() -> Self {
Self(Default::default(), Default::default())
}
}
impl<'de, K, V> Visitor<'de> for MapVisitor<K, V>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
{
type Value = HashMap<K, V>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("list of data")
}
fn visit_seq<A>(self, mut visitor: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut items = HashMap::with_capacity(visitor.size_hint().unwrap_or(0));
while let Some((k, v)) = visitor.next_element()? {
items.insert(k, v);
}
Ok(items)
}
}
deserializer.deserialize_seq(MapVisitor::default())
}
}
#[cfg(test)]
mod test {
use serde::{Deserialize, Serialize};
use crate::{from_bytes, from_data, to_bytes, Data, Error};
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
struct Parsed<T: std::str::FromStr + std::fmt::Display>(#[serde(with = "super::parse")] T)
where
T::Err: std::fmt::Display;
#[test]
fn parse_from_any_string() {
for data in [&b"+-12\r\n"[..], b"$3\r\n-12\r\n", b":-12\r\n"] {
let (res, rem) = from_bytes::<Parsed<i64>>(data).unwrap();
assert_eq!(res, Parsed(-12));
assert_eq!(rem, []);
}
let (res, _) = from_bytes::<Parsed<f64>>(b"$4\r\n1.25\r\n").unwrap();
assert_eq!(res, Parsed(1.25));
let (res, _) = from_bytes::<Parsed<String>>(b"$3\r\nfoo\r\n").unwrap();
assert_eq!(res, Parsed("foo".to_owned()));
let (res, _) = from_bytes::<Parsed<String>>(b":42\r\n").unwrap();
assert_eq!(res, Parsed("42".to_owned()));
}
#[test]
fn parse_from_data() {
let res = from_data::<Parsed<u64>>(Data::BulkString(b"42".to_vec().into())).unwrap();
assert_eq!(res, Parsed(42));
}
#[test]
fn parse_invalid() {
for data in [
&b"$3\r\nfoo\r\n"[..],
b"$2\r\n\xff\xfe\r\n",
b"$-1\r\n",
b"*0\r\n",
] {
let err = from_bytes::<Parsed<i64>>(data).unwrap_err();
assert!(matches!(err.data, Error::Message(_)), "{:?}", err);
}
}
#[test]
fn parse_serialize() {
let mut buf = Vec::new();
to_bytes(&Parsed(-12), &mut buf).unwrap();
assert_eq!(buf, b"$3\r\n-12\r\n");
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
struct Borrowed<'a>(#[serde(borrow, with = "super::str")] &'a str);
#[test]
fn str_borrowed() {
for data in [&b"+foo\r\n"[..], b"$3\r\nfoo\r\n"] {
let (res, rem) = from_bytes::<Borrowed>(data).unwrap();
assert_eq!(res, Borrowed("foo"));
assert_eq!(rem, []);
}
let res = from_data::<Borrowed>(Data::BulkString(b"foo"[..].into())).unwrap();
assert_eq!(res, Borrowed("foo"));
}
#[test]
fn str_invalid() {
for data in [&b"$2\r\n\xff\xfe\r\n"[..], b":1\r\n", b"$-1\r\n", b"*0\r\n"] {
let err = from_bytes::<Borrowed>(data).unwrap_err();
assert!(matches!(err.data, Error::Message(_)), "{:?}", err);
}
}
#[test]
fn str_owned() {
let data = Data::BulkString(b"foo".to_vec().into());
let err = from_data::<Borrowed>(data).unwrap_err();
assert!(matches!(err, Error::Message(_)), "{:?}", err);
}
#[test]
fn str_serialize() {
let mut buf = Vec::new();
to_bytes(&Borrowed("foo"), &mut buf).unwrap();
assert_eq!(buf, b"$3\r\nfoo\r\n");
}
}