I'm using tonic and tonic returns a Streaming<A>
, I want to turn it into a Box<dyn Stream<Item=B>>
, so the user of my function don't need to know about tonic detail.
I tried
stream.map(|val| (turns A into B))
which gives me a Map<Streaming<A>, |A| -> B>
, rather than a Stream<B>
that I want.
Stream<Item = B>
is a trait, not a type, so no value can be one. However, Map<Streaming<A>, |A| -> B>
does implement Stream<Item = B>
, which means it can be coerced into dyn Stream<Item = B>
, which is a type. This trait object is put behind a pointer type (Box
in this case) because it is unsized.
let new_stream = stream.map(|val| b(val));
Box::new(new_stream) as Box<dyn Stream<Item = B>>
It's likely you can leave off the as
cast, since type inference will pick it up in most cases.
It may be possible to return impl Stream<Item = B>
instead, which allows you to remove the Box
. This hides the inner type from your public API.
Also note that TryStream
and TryStreamExt
are useful for streams that return Result
(they can be difficult to discover on your own). You should still return impl Stream
or dyn Stream
since those can be used as TryStream
, but TryStream
can't always be used as Stream
. But you can use their methods inside your implementation.