How do I use serde to serialize a HashMap with non-serializable keys?

Viewed 1137

I have a HashMap as a value in a struct that I'm manually serializing:

pub struct GitInfo {
    pub branches: HashMap<Oid, Branch>,
}

Branch is something I've defined, but Oid is an external type I don't own, with a to_string() method I'd be happy to use...

I've read How do I use Serde to serialize a HashMap with structs as keys to JSON? but it refers to keys the author defined - I can't implement Serialize for Oid as it's not in my crate. And I can't implement Serialize for HashMap<Oid, Branch> for similar reasons.

Is there some way around this? I could build a wrapper struct around HashMap<Oid, Branch> but that seems like overkill.

It was suggested that I look at How to transform fields during serialization using Serde? or How can I implement Serialize using an existing Display trait implementation? - both seem to boil down to using serialize_with - which I could possibly do, but I'd have to use the derive(Serialize) macro, when I was planning to serialize GitInfo manually (see below). Or I could use a wrapper object.

If those are the only options, I could live with it, but it seems a bit surprising that there isn't a simpler way - is there some way to call a function like the serialize_with macro uses, but from within my GitInfo serialization?

Something like:

impl Serialize for GitInfo {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut state = serializer.serialize_struct("GitInfo", 2)?;
        state.serialize_field("other bits", &self.other_bits)?;
        state.serialize_field("branches", /* something */)?;
        state.end()
    }
}
0 Answers
Related