Search code examples
rustrust-tokio

`RwLockWriteGuard<'_, T>` does not implement the traits T implements


I would like to deserialize JSON objects from a stream, however that stream is wrapper in a RwLock. So the following does not work:

let mut stream:RwLockWriteGuard<'_, I2pStream> = wrapped_stream.write().await; // I2pStream implements the `Read` and `Write` Traits
let iterator = serde_json::Deserializer::from_reader(stream).into_iter::<serde_json::Value>();
for item in iterator {
  // ...
}

...since the trait 'std::io::Read' is not implemented for 'tokio::sync::RwLockWriteGuard<'_, I2pStream>'. I expected the RwLockWriteGuard would implement all traits its content type implements, since I can also call functions like read(), read_buf(...) etc. on the write guard (which are the Read trait's functions).

So is there a way to let the compiler know my write guard indeed does implement the std::io::Read trait? Or is there some other solution like wrapping the write guard in something which is a reader?


Solution

  • RwLockWriteGuard<'_, T> derefs into a T, so it gets all of T’s methods, but it does not automatically implement the traits that T implements. The issue is that serde_json::Deserializer::from_reader needs a Read, but only I2pStream, not RwLockWriteGuard<'_, I2pStream>, implements Read.

    I think you can solve this by simply forcing the Deref: serde_json::Deserializer::from_reader(&mut *stream); the blanket impl<R: Read + ?Sized> Read for &mut R should be sufficient.