There are languages that give you this guarantee, and yet don't require you to write the serialization code by hand.
Frankly, with something like serde in Rust, it's such a pain to deviate from the 1:1 case that you tend to stick to the 1:1 datastructure despite how suboptimal it is, maybe manually transforming it after parse time if you can be bothered. I don't find that to be any superior to Elm's simple combinators.
My experience with Elm's codecs is that there's a small learning curve if the concept is new to you. And then after some real world experience you wonder how it was ever alien at all. I wish I had it in every other language I've worked with.
http://hackage.haskell.org/package/aeson-1.4.5.0/docs/Data-A...