Skip to content

Channel API to select values #470

Open
@Thomasdezeeuw

Description

@Thomasdezeeuw

I'm looking for API that can remove any value from the channel based on user select. In other words I need a channel that is FIFO, but allows any value to removed if needed. For example I would like to be able to handle values with a higher priority before regular values.

For this purpose I though of the following design. It loops over all values currently in the channel allowing the user to select the value to receive next, e.g. the one with the highest priority. The user returns some type that indicates what message to remove, using that type the message is removed and returned to the user.

impl<T> Recevier<T> {
    /// Attempt to select a message to remove from the channel.
    pub fn try_select<S>(&mut self, mut selector: S) -> Option<T>
    where
        S: ValueSelector<T>,
    {
        selector.select(Values { recv: self })
            .map(|selection| { /* remove and return selection. */ })
    }
}

pub trait ValueSelector<M> {
    /// Select what value to receive.
    ///
    /// User looks over all values in `Values` and returns a `ValueSelection`, that
    /// message is removed from the channel.
    fn select<'m>(&mut self, values: Values<'m, M>) -> Option<ValueSelection>;
}

/// Iterates over all values currently in the channel.
#[derive(Debug)]
pub struct Values<'r, M> {
    recv: &'r mut Receiver<M>,
}

impl<'r, T> Iterator for Values<'m, T> {
    type Item = (MessageSelection, &'r T);

    fn next(&mut self) -> Option<Self::Item> {
        // Loop over all values in the channel, by reference.
    }
}

/// The type used to indicate what message to select.
#[derive(Copy, Clone, Debug)]
pub struct MessageSelection(/* usize ? */);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions