-
Notifications
You must be signed in to change notification settings - Fork 562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weird behaviour when deserializing a RawValue
through a Visitor
.
#1150
Comments
In fact, going through a simple passthrough visitor failsuse serde::{de::value::*, Deserialize};
#[cfg(test)]
use serde_json::{json, value::RawValue, Value};
use std::marker::PhantomData;
#[derive(Debug)]
struct Passthrough<T>(T);
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Passthrough<T> {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self(deserializer.deserialize_any(Visitor(PhantomData))?))
}
}
struct Visitor<T>(PhantomData<fn() -> T>);
impl<'de, T> serde::de::Visitor<'de> for Visitor<T>
where
T: Deserialize<'de>,
{
type Value = T;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("AAAAA")
}
fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<Self::Value, E> {
T::deserialize(BoolDeserializer::new(v))
}
fn visit_i8<E: serde::de::Error>(self, v: i8) -> Result<Self::Value, E> {
T::deserialize(I8Deserializer::new(v))
}
fn visit_i16<E: serde::de::Error>(self, v: i16) -> Result<Self::Value, E> {
T::deserialize(I16Deserializer::new(v))
}
fn visit_i32<E: serde::de::Error>(self, v: i32) -> Result<Self::Value, E> {
T::deserialize(I32Deserializer::new(v))
}
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Self::Value, E> {
T::deserialize(I64Deserializer::new(v))
}
fn visit_i128<E: serde::de::Error>(self, v: i128) -> Result<Self::Value, E> {
T::deserialize(I128Deserializer::new(v))
}
fn visit_u8<E: serde::de::Error>(self, v: u8) -> Result<Self::Value, E> {
T::deserialize(U8Deserializer::new(v))
}
fn visit_u16<E: serde::de::Error>(self, v: u16) -> Result<Self::Value, E> {
T::deserialize(U16Deserializer::new(v))
}
fn visit_u32<E: serde::de::Error>(self, v: u32) -> Result<Self::Value, E> {
T::deserialize(U32Deserializer::new(v))
}
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Self::Value, E> {
T::deserialize(U64Deserializer::new(v))
}
fn visit_u128<E: serde::de::Error>(self, v: u128) -> Result<Self::Value, E> {
T::deserialize(U128Deserializer::new(v))
}
fn visit_f32<E: serde::de::Error>(self, v: f32) -> Result<Self::Value, E> {
T::deserialize(F32Deserializer::new(v))
}
fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<Self::Value, E> {
T::deserialize(F64Deserializer::new(v))
}
fn visit_char<E: serde::de::Error>(self, v: char) -> Result<Self::Value, E> {
T::deserialize(CharDeserializer::new(v))
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
T::deserialize(StrDeserializer::new(v))
}
fn visit_borrowed_str<E: serde::de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
T::deserialize(BorrowedStrDeserializer::new(v))
}
fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
T::deserialize(StringDeserializer::new(v))
}
fn visit_bytes<E: serde::de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
T::deserialize(BytesDeserializer::new(v))
}
fn visit_borrowed_bytes<E: serde::de::Error>(self, v: &'de [u8]) -> Result<Self::Value, E> {
T::deserialize(BorrowedBytesDeserializer::new(v))
}
fn visit_byte_buf<E: serde::de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
T::deserialize(BytesDeserializer::new(&v))
}
fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
T::deserialize(UnitDeserializer::new())
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
T::deserialize(deserializer)
}
fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
T::deserialize(UnitDeserializer::new())
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
T::deserialize(deserializer)
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
T::deserialize(SeqAccessDeserializer::new(seq))
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
T::deserialize(MapAccessDeserializer::new(map))
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::EnumAccess<'de>,
{
T::deserialize(EnumAccessDeserializer::new(data))
}
}
#[test]
fn wrapped() {
// normal value
serde_json::from_value::<Passthrough<Value>>(json!(null)).unwrap();
serde_json::from_value::<Passthrough<Value>>(json!(1)).unwrap();
serde_json::from_value::<Passthrough<Value>>(json!("s")).unwrap();
serde_json::from_value::<Passthrough<Value>>(json!({})).unwrap();
serde_json::from_value::<Passthrough<Value>>(json!([])).unwrap();
// raw value
serde_json::from_value::<Passthrough<Box<RawValue>>>(json!(null)).unwrap(); // boom
serde_json::from_value::<Passthrough<Box<RawValue>>>(json!(1)).unwrap(); // boom
serde_json::from_value::<Passthrough<Box<RawValue>>>(json!("s")).unwrap(); // boom
serde_json::from_value::<Passthrough<Box<RawValue>>>(json!({})).unwrap(); // boom
serde_json::from_value::<Passthrough<Box<RawValue>>>(json!([])).unwrap(); // boom
} |
aatifsyed
changed the title
Weird behaviour when serializing a
Weird behaviour when deserializing a Jul 1, 2024
RawValue
through a Visitor
.RawValue
through a Visitor
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In a variation of the
StringOrStruct
example in the docs, I'm writing the following "filter" for deserializers:It works as expected when wrapping a
serde_json::Value
But I get false negatives when using
serde_json::value::RawValue
:The error messages are a little odd:
full example on playground
I can't tell if my Visitor is bugged, but I think I assumed that if it worked for
Value
it should work forRawValue
.We fall over at line
355
:json/src/raw.rs
Lines 340 to 359 in b48b9a3
The text was updated successfully, but these errors were encountered: