[Solved] Changing types during serialization/deserialization

#1

I would like to be able to serialize a [char;32] into a String and deserialize it back to [char;32]. I’ve tried serialize_with, but that doesn’t let me change the type. Since I’m doing this for a large number of structs that implement the same trait, I’d like to avoid writing a separate custom serializer and deserializer for each struct. I managed to put all the serialization code in one place and specialize it for each struct, but I could figure out how to do that for the deserializer.

#2

serialize_with should be fine. Note that it will take a String, but then you have freedom to call array-serializing methods on the serializer instead.

BTW: [char;32] is a very peculiar type. Did you mean [u8;32]? char in Rust is a Unicode codepoint that takes 4 bytes.

#3

My bad, I had an “&” where I shouldn’t have, and the compiler was telling me my
#[derive(Serialize)] was expecting [char; 32]. (I’m using char because the characters in the array come from a string.)

I’ve got serialize_with working. I haven’t done deserialize_with yet. The problem is that I have a gazillion structs that implement a specific trait that has the [char;32]. It’s only 2 lines of code to serialize all these structs (2, not 2 per struct even). I’m trying to implement deserialize_with using T: Foo, where Foo is the trait.

Maybe there’s a better way to do what I’m using the array for. I have a struct with a String and a Copy type. Clearly the struct isn’t Copy, but I would like it to be to avoid sprinkling clone() all over my code like pepper on scrambled eggs. I also have several places where the borrow checker complains that I need to work around. If I encode the String as a [char;32], the struct is Copy. Woo Hoo! Unfortunately, our trace analyzer, which uses serialized JSON, is expecting a String for that field.

#4

You can wrap it in a newtype struct ShortString([char;32]) and make that serializable.

If you want stack-allocated stings, try arrayvec (includes ArrayString).

#5

Of course! (I have a problem getting locked into an approach and not seeing something far simpler. On the positive side, I did learn about custom serialization.) ArrayString looks even better.

#6

I first tried arrayvec, but I got some error that I interpreted as saying it doesn’t work with stable. I then created a new type as @kornel suggested, but that added another level to the JSON struct, which also broke the trace analyzer.

However, once I figured out how serailze_with and deserialize_with work, I was able to handle the gazillion structs that implement the trait with a few lines of generic code.