I have a struct I'm using for serde serialization:
pub struct CdrSerializer<W> where W: Write {
pub endianness: CdrEndianness,
pub write_handle: W
}
and in some scenarios (mainly testing) I want to use a std::io::Cursor value for the write_handle:
let new_slice = &mut buf[..];
let writeable_buf = Cursor::new(new_slice);
let mut serializer = CdrSerializer{
endianness: CdrEndianness::Big,
write_handle: writeable_buf
};
now the big thing is I'd like to get the position on the cursor. how can I keep the generic code but add a position if I know the type parameter is std::io::Cursor?
error[E0243]: wrong number of type arguments
--> src/cdr/ser.rs:61:37
|
61 | impl Positionable for CdrSerializer<Cursor> {
| ^^^^^^ expected 1 type arguments, found 0
You're actually pretty close! The issue is that Cursor<T> is itself a generic type, so you need to be able to provide a type bound for it.
Something like this should work:
impl <T> Positionable for CdrSerializer<Cursor<T>>
Looking at the docs for Cursor it looks like a good bound for that T above could be AsRef<[u8]>, if you need to work with bytes in the position method. So if that was the case your impl would look like:
impl <T: AsRef<[u8]>> Positionable for CdrSerializer<Cursor<T>>
Ah, great insight! That got me unblocked. But then I realized I had the CdrSerializer in scope and the write_handle property could be accessed by its concrete type -- so I didn't even need the Positionable trait!
For some reason I thought once assigned to the write_handle property the value could be accessed as through 'Write' interface.
Ah gotcha Rust has decent inference on its generics, so in a lot of cases they're omitted, but still there, quietly making the world a better place. So if we put the generics back in your above sample, you can see why you can access your write_handle as more than just Write:
let mut serializer: CdrSerializer<Cursor<&mut [u8]>> = CdrSerializer { ... }
let cursor: Cursor<&mut [u8]> = serializer.write_handle;
let position = cursor.position;
It'll actually be a compile error, because the types are known at compile-time. This is the best possible outcome because it means if that code is running it'll always work as advertised.