tokio icon indicating copy to clipboard operation
tokio copied to clipboard

StreamMap::try_insert

Open nashley opened this issue 3 years ago • 1 comments

Is your feature request related to a problem? Please describe. I'd like to ensure uniqueness of streams in a StreamMap without panicking.

Describe the solution you'd like std added support for {BTreeMap,HashMap}::try_insert to nightly, but it has not yet been stabilized.

I'd like for a similar method to be added to tokio_stream::StreamMap. This may need to wait until std's implementation has stabilized.

Describe alternatives you've considered The calling code could, if replacing a stream is acceptable, call tokio_stream::StreamMap::insert and match on the returned Option<V>, dealing with Some(V) as appropriate to the application:

let mut streams = tokio_stream::StreamMap::new();
streams.insert("key", tokio_stream::pending::<u8>());
// ...
match streams.insert("key", tokio_stream::pending::<u8>()) {
    Some(existing_stream) => {
        streams.insert("key", existing_stream);
        println!("Double-replaced existing stream");
    }
    None => {}
}

The calling code could also check for the existence of the key first and handle collisions before insertion, but doing so would waste an iteration through the map's entries:

let mut streams = tokio_stream::StreamMap::new();
streams.insert("key", tokio_stream::pending::<u8>());

if streams.contains_key("key") {
    println!("{} already exists in stream map; ignoring", "key");
} else {
    streams.insert("key", tokio_stream::pending::<u8>());
}

The calling code could use tokio_stream::StreamMap::extend instead to avoid the redundant iteration, but that relies on an implementation detail that may be removed as part of #4774.

Additional context It would probably be a good idea to wait until the feature has stabilized in std unless tokio_stream being a separate crate means that it is acceptable to make backwards-incompatible changes more frequently.

nashley avatar Jun 17 '22 11:06 nashley

As pointed out in this comment, or_insert() (e.g., map.entry("key").or_insert(tokio_stream::pending::<u8>())) could be used if the desired behavior is to preserve existing keys. However, StreamMap doesn't (yet) have Entry as a concept, and I'm not sure that it's worth adding.

nashley avatar Jun 26 '22 16:06 nashley