macro_rules! Stream { () => { ... }; ($l:lifetime) => { ... }; ($channel:ident => $($token:tt)*) => { ... }; }
Expand description
Type and expression macro for async
WebSocket Message
streams.
This macro can be used both where types are expected or where expressions are expected.
§Type Position
When used in a type position, the macro invoked as Stream['r]
expands to:
MessageStream
<'r, impl
Stream
<Item =
Result
<
Message
>>> + 'r>
The lifetime need not be specified as 'r
. For instance, Stream['request]
is valid and expands as expected:
MessageStream
<'request, impl
Stream
<Item =
Result
<
Message
>>> + 'request>
As a convenience, when the macro is invoked as Stream![]
, the lifetime
defaults to 'static
. That is, Stream![]
is equivalent to
Stream!['static]
.
§Expression Position
When invoked as an expression, the macro behaves similarly to Rocket’s
stream!
macro. Specifically, it
supports yield
and for await
syntax. It is invoked as follows:
use rocket_ws as ws;
#[get("/")]
fn echo(ws: ws::WebSocket) -> ws::Stream![] {
ws::Stream! { ws =>
for await message in ws {
yield message?;
yield "foo".into();
yield vec![1, 2, 3, 4].into();
}
}
}
It enjoins the following type requirements:
- The type of
ws
must beWebSocket
.ws
can be any ident. - The type of yielded expressions (
expr
inyield expr
) must beMessage
. - The
Err
type of expressions short-circuited with?
must beError
.
The macro takes any series of statements and expands them into an expression
of type impl Stream<Item =
Result
<T>>
, a stream that yield
s elements of
type Result
<T>
. It automatically converts yielded items of type T
into
Ok(T)
. It supports any Rust statement syntax with the following
extensions:
-
?
short-circuits stream termination onErr
The type of the error value must be
Error
.
-
yield expr
Yields the result of evaluating
expr
to the caller (the stream consumer) wrapped inOk
.expr
must be of typeT
.
-
for await x in stream { .. }
await
s the next element instream
, binds it tox
, and executes the block with the binding.stream
must implementStream<Item = T>
; the type ofx
isT
.
§Examples
Borrow from the request. Send a single message and close:
use rocket_ws as ws;
#[get("/hello/<user>")]
fn ws_hello(ws: ws::WebSocket, user: &str) -> ws::Stream!['_] {
ws::Stream! { ws =>
yield user.into();
}
}
Borrow from the request with explicit lifetime:
use rocket_ws as ws;
#[get("/hello/<user>")]
fn ws_hello<'r>(ws: ws::WebSocket, user: &'r str) -> ws::Stream!['r] {
ws::Stream! { ws =>
yield user.into();
}
}
Emit several messages and short-circuit if the client sends a bad message:
use rocket_ws as ws;
#[get("/")]
fn echo(ws: ws::WebSocket) -> ws::Stream![] {
ws::Stream! { ws =>
for await message in ws {
for i in 0..5u8 {
yield i.to_string().into();
}
yield message?;
}
}
}