Closed hirenhpatel closed 1 month ago
Usually you would implement DeserializeSeed
on the same type that also has the corresponding Visitor
impl. So a canonical impl would look like:
impl<'de> DeserializeSeed<'de> for TheVisitor {
type Value = <Self as Visitor<'de>>::Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_………(self)
}
}
The thought of implementing DeserializeSeed
on Visitor
never occurred to me! After studying your suggestion some more, I have settled on the pattern of having a surrogate nested visitor type DynamicVisitor<TupleVisitor<..., NodeVisitor<...>>
that mirrors the target deserialization datatype: Dynamic<(..., NodeVisitor<...>)>
.
I have implemented DeserializeSeed<'de>
on all of the *Visitor
structs, which have the metadata as needed. Then, most of the my deserialize calls look like this
deserializer.deserialize_*(self.0)
to pass the inner visitor to the next step in the recursion.
Have I understand your guidance correctly?
Further, do I understand correctly that, in my recursive deserialization implementations, I should
not mix Deserialize
with DeserializeSeed
? That is, in any chain, I will be dealing with Deserialize<'de>
exclusively, or with DeserializeSeed<'de>
exclusively?
Thanks in advance
I have data types that need to be deserialized from json that look like this:
The datatypes that appear are quite varied, and as a result, I am essentially writing my own implementations of
Deserialize
.I have now reached a situation where I need extra information (let's call it
MyMetadata
) to properly deserialize theNode
struct.Happily, I found
DeserializeSeed
and started to rewrite all myDeserialize
implementations toDeserializeSeed
implementations since I can then utilize the extraseed
to argument pipeMyMetadata
through deserialization. My thought here isMyMetadata
tags along for the ride remaining unused, until aNode
is encountered by theVisitor
at which point I can use it to facilitate deserialization.Unfortunately, I've run into an awkward problem: it seems that I'm not supposed to implement
DeserializeSeed
onDynamic
,Scalar
,Float
like I am supposed to inDeserialize
. Rather, I'm supposed to implement it on a new data structure, and the associated return type is supposed to be one ofDynamic
,Scalar
,Float
. With that interface, it's not clear to me how I should be usingDeserializeSeed
to move theMyMetadata
through the deserialization process?Should I add an unused generic parameter on
MyMetadata
and implementDeserializeSeed
on the various concrete types, converting them to other concrete types in my implementation ofVisitor
?