Change serialized field names from other crates

I'm working on a distributed system which requires that all objects in JSON use camelCase field names.

On my own structs this is simple with: #[serde(rename_all = "camelCase")]

But now I want to use structs from an external/public crate that didn't specify a naming convention, so uses the default snake case for field names.

#[derive(Default, Clone, Serialize, Deserialize)]
pub struct SomeExternalThing {
    some_field_name: String,
    ...
};

So this will serialize as { "some_field_name": "string contents" }

Is there away to force this external type into using camelCase without redefining the whole struct? So that it serializes as: { "someFieldName": "string contents" }

Thanks

The only way to do this is duplicating the structure with your own serialization requirements satisfied. See Derive for remote crate · Serde, which covers a similar situation where the remote type does not implement the serde traits at all. The only difference in your case is that the remote type does implement the traits, but the implementations are not usable.

Rust does not allow external types to do anything they are not designed to do. What you can do is customize its behavior with your own trait (e.g. the extension trait pattern) or provide your own type (may or may not be a newtype) to implement an external trait on the external type. The latter is exactly what the "Derive for remote crate" example does. But it's kind of unique because it handles the conversion/wrapping for you.


I also just came across this, which might be a hint that the underlying serializer can be reused for values. You would just provide customization for the keys: enum variant deserialize_with · Issue #1174 · serde-rs/serde

Thanks, @parasyte!
That's not as easy as I'd hoped, but definitely not as bad as I feared either. I think it should work. I was unaware of the "remote" attribute.

Alas, this does not work:

Related issue: