Closed bradleyharden closed 1 year ago
Hi! That's a good question. I'd recommend you consider using Stream::merge
instead:
enum Message<T> {
Data(T),
End,
}
let data = stream::once(future.map(Message::Data));
let end = signal.map(|_| Message::End);
let mut s = (data, end).merge();
while let Some(msg) = s.next().await {
match msg {
Data(data) => ..,
End => break,
}
}
I describe how this works in more detail here.
Ah, that's a good idea. I didn't think to use the fact that Signals
already implements Stream
. Using .map()
certainly helps cut down on the boilerplate too.
Thanks for the tip. I think this is clean enough for me to justify moving away from a macro.
Hi,
I'm in the process of converting a small project of mine from
tokio
tosmol
. In the process, I'm also removing instances oftokio::select!
and replacing them with constructs fromfutures-concurrency
. For the most part, the changes have been simple. That's great, because I would prefer to avoid macros if they don't significantly simplify the code.However, I think I found one instance where the macro wins out. I wanted to bring it up here, since I don't see any existing issues discussing it.
I had loop that would
await
either more data or a signal. If I got a signal, I would break the loop.Implementing this with
Race
is a bit tricky. You need to somehow unify the types. I choseControlFlow
, as it seemed the most natural. Here's what I came up with:Can you think of any better way to implement this? I think this is one area where the macro has a natural advantage. Is there any simpler way to do this in the
smol
ecosystem?