Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

feat: add EventStream::select to combine multiple event streams #725

Merged
merged 2 commits into from
Dec 23, 2021

Conversation

mattsse
Copy link
Collaborator

@mattsse mattsse commented Dec 22, 2021

Motivation

Combine multiple EventStream with different items

Solution

PR Checklist

  • Added Tests
  • Added Documentation
  • Updated the changelog

{
/// Turns a stream of Results to a stream of `Result::ok` for both arms
pub fn ok(self) -> Pin<Box<dyn Stream<Item = Either<L, R>> + 'a>> {
Box::pin(self.filter_map(|e| async move {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want the filter_map here? Won't this silently eat all errors if any are observed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes this skips all erroneous values, but is probably useful if you're only interested in the ok values.

///
/// # }
/// ```
pub fn select<St>(self, st: St) -> SelectEvent<SelectEither<'a, Result<R, E>, St::Item>>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder if there's a world where we do this with a macro instead of a function (like the futures select!), so that we are not limited to only selecting 2 events?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

driving multiple streams to completion with select! is a bit verbose and the core problem is that we need to return a type that represents all the different events.
you can do this with EventStream::select

let ev3 = contract.event::<OtherEvent>();

let stream = ev3.stream().await().unwrap().select(
   ev1.stream().await.unwrap().select(ev2.stream().await.unwrap())
);

which will return an Either<OtherEvent, Either<Approval, Transfer>>

But there'd be also the possibility to create your own event type and use the Contract::event_with_filter function

 #[derive(Debug, Clone, PartialEq, Eq)]
    pub enum Events {
        Approval(Approval),
        Transfer(Transfer),
        Other(Other),
    }
  impl EthLogDecode for Events {...}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right! OK if that pattern works then should be fine.

@gakonst gakonst merged commit 11406ee into gakonst:master Dec 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants