I want to implement serialization for a network protocol with many different types, which might also be nested. As an example, let's assume that the only types are Vector3 and Tuple. I have this written out in the playground: Rust Playground
I want implementation of new types to be as easy as possible, so instead of an enum I've chosen to use a trait (Value) which all values should implement. Because the write() method takes a generic Write type argument, it's not method safe for dynamic dispatch, so I've also created a DynValue trait, which takes &mut dyn Write. If possible, I would like to be use both the dynamic dispatch version and generic version. However, I can't manage to call DynValue::write. The compiler tells me:
error[E0277]: the size for values of type `W` cannot be known at compilation time
--> src/main.rs:41:21
|
38 | fn write<W: Write + ?Sized>(&self, stream: &mut W) -> io::Result<()> {
| -- help: consider further restricting this bound: `W: std::marker::Sized +`
...
41 | v.write(stream)?;
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `W`
And if I remove the ?Sized annotations from everything, the DynValue impl fails to call the concrete Value::write, because &mut dyn Write might not be Sized:
error[E0277]: the size for values of type `dyn std::io::Write` cannot be known at compilation time
--> src/main.rs:14:24
|
5 | fn write<W: Write>(&self, stream: &mut W) -> io::Result<()>;
| ------------------------------------------------------------ required by `Value::write`
...
14 | V::write(self, stream)
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn std::io::Write`
Is there a better way to approach what I'm attempting?