Skip to content

add ObjectId deserialization from sequence to support messagepack #457

@univerz

Description

@univerz

de/serializing ObjectId works when using rmp_serde::encode::to_vec_named, but not with rmp_serde::encode::to_vec which stores object as an array without field keys. example how it looks like:

#[derive(Deserialize, Serialize, Debug)]
struct Test {
    objectid: ObjectId,
    float: f64,
}
let test = Test { objectid: ObjectId::new(), float: 3.14 };

let buf = rmp_serde::encode::to_vec_named(&test)?;
dbg!(rmp_serde::from_slice::<RmpValue>(buf.as_slice())?);
let buf = rmp_serde::encode::to_vec(&test)?;
dbg!(rmp_serde::from_slice::<RmpValue>(buf.as_slice())?);
Ok(())
output
rmp_serde::from_slice::(buf.as_slice())? = Map(
    [
        (
            String(
                Utf8String {
                    s: Ok(
                        "objectid",
                    ),
                },
            ),
            Map(
                [
                    (
                        String(
                            Utf8String {
                                s: Ok(
                                    "$oid",
                                ),
                            },
                        ),
                        String(
                            Utf8String {
                                s: Ok(
                                    "65c9e0a4e3f150942e7f537e",
                                ),
                            },
                        ),
                    ),
                ],
            ),
        ),
        (
            String(
                Utf8String {
                    s: Ok(
                        "float",
                    ),
                },
            ),
            F64(
                3.14,
            ),
        ),
    ],
)
rmp_serde::from_slice::(buf.as_slice())? = Array(
    [
        Array(
            [
                String(
                    Utf8String {
                        s: Ok(
                            "65c9e0a4e3f150942e7f537e",
                        ),
                    },
                ),
            ],
        ),
        F64(
            3.14,
        ),
    ],
)

because the ObjectId behavior is special, i (probably) need something like this added to ObjectIdVisitor to make it work (serialize_object_id_as_hex_string is not an option):

#[inline]
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
    V: SeqAccess<'de>,
{
    visitor.next_element::<ObjectId>()?.ok_or_else(|| {
        de::Error::custom(format!("failed to deserialize ObjectId from a sequence"))
    })
}

are you open to it, or do you see a better solution?

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions