Serde is also generic in the serialization format; the example I linked uses serde_json, and was adapted from its README here https://github.com/serde-rs/json
instance ToJSON Person where
toJSON = genericToJSON $ aesonPrefix snakeCase
instance FromJSON Person where
parseJSON = genericParseJSON $ aesonPrefix snakeCase
I haven't had to do snake_case to CamelCase with Aeson before, but I have dropped a prefix before, like "userName" -> "name", "userAge" -> "age", and it was pretty easy and well supported.
Also I would note that this isn't as big of a deal for Haskell and Rust, because they're primarily backend languages, so they're more often sending out JSON in whatever form they please, rather than consuming it. In my experience the main consumers (Javascript on the web, Objective-C on iOS and Java on Android) use CamelCase anyway, so there's a natural compatibility.
https://www.stackage.org/haddock/lts-9.0/aeson-casing-0.1.0....
Giving you automatic encoders/decoders like so:
instance ToJSON Person where toJSON = genericToJSON $ aesonPrefix snakeCase instance FromJSON Person where parseJSON = genericParseJSON $ aesonPrefix snakeCase
And the implementation of that package is like 4 simple lines for snake case; it's totally doable on your own for whatever you need https://github.com/AndrewRademacher/aeson-casing/blob/260d18...
I haven't had to do snake_case to CamelCase with Aeson before, but I have dropped a prefix before, like "userName" -> "name", "userAge" -> "age", and it was pretty easy and well supported.
Also I would note that this isn't as big of a deal for Haskell and Rust, because they're primarily backend languages, so they're more often sending out JSON in whatever form they please, rather than consuming it. In my experience the main consumers (Javascript on the web, Objective-C on iOS and Java on Android) use CamelCase anyway, so there's a natural compatibility.