title: Async unbuffered channel that blocks on read and on write
body: <p>For threaded applications, the Rust standard library provides <code>std::sync::mpsc::sync_channel</code>, a buffered channel which blocks on the reading end when the buffer is empty and blocks on the writing end when the buffer is full. In particular, if you set the buffer size to 0, then any read or write will block until there is a matching write or read.</p>
  <p>For async code, there is <code>futures::channel::mpsc::channel</code>, but this does not have the same behavior. Here the minimum capacity is the number of senders on the channel, which is greater than 0. The sending end can still block (because it implements <code>Sink</code>, so we can use <code>SinkExt::send</code> and <code>await</code> it), but only after there's at least one thing already in the buffer.</p>
  <p>I took a look to see if there were any packages that provide the functionality I'm looking for, but I could not find anything. <code>Tokio</code> provides lots of nice async synchronization primitives, but none of them did quite what I'm looking for. Plus, my program is going to run in the browser, so I don't think I'm able to use a runtime like <code>Tokio</code>. Does anyone know of a package that fits my use case? I would try to implement this myself, since this almost feels like the most minimal use case for the <code>Sink</code> and <code>Stream</code> traits, but even a minimal implementation of these traits seems like it would be really complicated. Thoughts?</p>
  <p>Edit: here's a minimal example of what I mean:</p>
  <pre class="lang-rust prettyprint-override"><code>fn main() {
    let (tx, rx) = blocking_channel();
  
    let ft = async move {
      tx.send(3).await;
      println!(&quot;message sent and received&quot;);
    }
  
    let fr = async move {
      let msg = rx.recv().await;
      println!(&quot;received {}&quot;, msg);
    }
  
    block_on(async { join!(ft, fr) });
  }
  </code></pre>
  <p>In this example, whichever future runs first will yield to the other, and only print after both <code>rx.recv</code> and <code>tx.send</code> have been called. Obviously, the receiving end can only progress after <code>tx.send</code> has been called, but I want the less obvious behavior of the transmitting end also having to wait.</p>