Safe/idiomatic conversion between different types that are binary-compatible


#1

I have two libraries, and each has their own struct RGB{r:u8,g:u8,b:u8}. I want to safely and without copying pass &[Foo::RGB] to function taking &[Bar::RGB].

What’s the proper way of doing this?

So far I’ve been using mem::transmute(), but maybe there’s a more elegant solution? I’ve tried hiding transmute in .into(), but E0117 and E0210 stopped me.


#2

I think it would be best to make them truly common types. Make Foo use Bar::RGB or vice-versa, or if these are independent crates then give them a common dependency that defines RGB.


#3

I’d wish for something like that too. I’d like to view BTreeMap<char, i32> as BTreeMap<char, Cell<i32>> or safely convert a &[u32] to &[i32] (which is similar to what you’re trying to do). There is a pod crate, but it only supports conversions from/to u8 (so you have to make a roundtrip through &[u8] in your case).

Btw, note that struct layout is undefined in Rust, make sure both crates use #[repr(C)] annotation.


#4

Since you cannot implement .into() on foreign types, why not just implement your own RGB and implement From for either of the other two crates?

I admit this kinda reminds me of this thing here:

( https://xkcd.com/927/ )

Perhaps you could also suggest to the owners of your dependencies to use a common crate for all, such as https://crates.io/crates/palette (which I haven’t looked at too closely), as @cuviper suggested.