From 45ae1c68eb4424d948ddeb09d4ea8c019428dc74 Mon Sep 17 00:00:00 2001 From: Pantonshire Date: Thu, 21 Jul 2022 13:29:09 +0100 Subject: [PATCH] Improved serde support --- Cargo.toml | 2 +- src/strings/inlining.rs | 59 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0625ccc..387dc5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [features] -default = ["std", "serde"] +default = ["std"] alloc = ["serde?/alloc"] std = ["serde?/std"] diff --git a/src/strings/inlining.rs b/src/strings/inlining.rs index 0a5acf5..1c7e5b5 100644 --- a/src/strings/inlining.rs +++ b/src/strings/inlining.rs @@ -5,11 +5,16 @@ use core::{ fmt, hash::{Hash, Hasher}, ops, - str::FromStr, + str::{self, from_utf8}, }; #[cfg(not(feature = "std"))] -use alloc::{borrow::Cow, boxed::Box, string::String}; +use alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + string::String, + vec::Vec, +}; #[cfg(feature = "std")] use std::borrow::Cow; @@ -292,7 +297,7 @@ impl Hash for InliningString { } } -impl FromStr for InliningString { +impl str::FromStr for InliningString { type Err = Infallible; #[inline] @@ -331,7 +336,53 @@ impl<'de, const N: usize> serde::Deserialize<'de> for InliningString { where D: serde::Deserializer<'de>, { - serde::Deserialize::deserialize(deserializer).map(Self::new::>) + use serde::de::{Error, Unexpected, Visitor}; + + struct InliningStringVisitor; + + impl<'de, const N: usize> Visitor<'de> for InliningStringVisitor { + type Value = InliningString; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a string") + } + + fn visit_str(self, v: &str) -> Result { + #[cfg(feature = "std")] { + println!("visit &str \"{}\"", v); + } + Ok(Self::Value::new(v)) + } + + fn visit_string(self, v: String) -> Result { + #[cfg(feature = "std")] { + println!("visit String \"{}\"", v); + } + Ok(Self::Value::new(v)) + } + + fn visit_bytes(self, v: &[u8]) -> Result { + #[cfg(feature = "std")] { + println!("visit &[u8] {:?}", v); + } + str::from_utf8(v) + .map(Self::Value::new) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } + + fn visit_byte_buf(self, v: Vec) -> Result { + #[cfg(feature = "std")] { + println!("visit Vec {:?}", v); + } + String::from_utf8(v) + .map(Self::Value::new) + .map_err(|err| { + Error::invalid_value(Unexpected::Bytes(&err.into_bytes()), &self) + }) + } + } + + deserializer.deserialize_string(InliningStringVisitor) } }