Validate that a tokio Sender and Receiver belong to the same channel

⚓ Rust    📅 2026-04-08    👤 surdeus    👁️ 5      

surdeus

I have an API where I need a user to pass in the Receiver of a tokio::sync::mpsc::channel into the factory method of a struct.
Within the struct's private functions I also need the ability to send to that very receiver, so I also need a copy of the appropriate Sender.

I do not want to create the channel within the factory method, because that would make the API weird, since I'd then need to return (Self, Sender<T>) from it and also pass in the desired channel size, which I don't care about in the context of that struct.

However, just accepting a Sender<T> and a Receiver<T> does not guarantee them belonging to the same channel.

Sender has a same_channel() method, but it only accepts another Sender. I cannot use it to check whether it is on the same channel as a Receiver.

So my question is whether I can validate that somehow? I'm fine returning an appropriate Result from the factory method in question.

The only other option I can think of is to mark the factory function unsafe and require the user to uphold the invariant that Sender and Receiver are on the same channel.

PS: Another option, which is only half-bad is to require the user to curry the channel function so that I don't need to pass in the channel size:

impl Gestures {
    /// Create a new gesture handler.
    #[must_use]
    pub fn new<F>(
        f: F,
        gestures: Sender<Gesture>,
        double_click_timeout: Duration,
    ) -> (Self, Sender<Message>)
    where
        F: FnOnce() -> (Sender<Message>, Receiver<Message>),
    {
        let (messages_out, messages_in) = f();
        (
            Self {
                messages_out: messages_out.clone(),
                messages_in,
                gestures,
                cache: Mutex::new(HashSet::new()),
                double_click_timeout,
            },
            messages_out,
        )
    }
}

...

let (gestures_demux, messages_out) = Gestures::new(|| channel(42), ...);

But this still does not guarantee, that the Sender and Receiver returned from the function belong to the same channel.

5 posts - 3 participants

Read full topic

🏷️ Rust_feed